Literal Syntax for NSArray, NSDictionary & NSNumber

2»

Réponses

  • 'ldesroziers' a écrit:


    Joli troll




    Toujours présent quand il est question de le suivre ^^
  • Déjà  que sur Twitter tu te donnes à  fond ... image/grin.gif' class='bbc_emoticon' alt=';D' />
  • Je crois que j'ai loupé un épisode, j'ai la dernière version d'XCode mais cette nouvelle syntaxe ne passe pas, y a un patch à  récupéré quelque part ?
  • Je crois que c'est uniquement dans la beta de Xcode 4.4 (fournie avec Mountain Lion).



    Pour avoir cette feature avec le Xcode actuel, je crois qu'il faut se compiler la dernière version de LLVM.
  • 'yoann' a écrit:


    La quantité de mots clef du langage n'a d'impact que jusqu'à  la compilation, ensuite on est en langage machine... C'est pas du Java hein :-)




    Je ne parlais pas des performances, je parlais de l'utilisation du langage, la mémorisation de ses concepts. Je pense que plus il y a de concepts différents, de mots clés, moins les programmeurs l'utilisent à  fond. C'est un peu comme Word et Excel, il y a plein de fonctions que personne n'utilise car elles sont inaccessibles au premier abord. Alors faut-il un langage plein de fonctions inutilisées ou un langage tout simple que tout le monde maà®trise ? Etant entendu que simple ne veut pas forcément dire limité. Boaf.
  • 'groumpf' a écrit:


    Je ne parlais pas des performances, je parlais de l'utilisation du langage, la mémorisation de ses concepts. Je pense que plus il y a de concepts différents, de mots clés, moins les programmeurs l'utilisent à  fond. C'est un peu comme Word et Excel, il y a plein de fonctions que personne n'utilise car elles sont inaccessibles au premier abord. Alors faut-il un langage plein de fonctions inutilisées ou un langage tout simple que tout le monde maà®trise ? Etant entendu que simple ne veut pas forcément dire limité. Boaf.




    C'est un autre débat mais je ne trouve pas le C spécialement surfait... Un switch case dispose d'avantage indéniable sur un if en cas de liste longue... C'est pas vital mais c'est pratique, comme la syntaxe pointé des accesseurs.
  • CéroceCéroce Membre, Modérateur
    @groumpf: je suis entièrement d'accord avec toi.



    Le langage C, par exemple, parmi ses défauts, a l'avantage d'être succinct dans sa syntaxe. Apple dénature Objective-C avec tous ses ajouts: propriétés déclarées, ARC et maintenant syntaxe littérale. Je comprends le besoin de rendre le code plus abstrait (voire, plus rapide à  taper), mais en même temps, les anciennes contraintes sont toujours là :
    • ça m'arrive encore souvent d'écrire des setters à  la mano, avec les -retain, le KVO et tout le tintouin.
    • ARC n'est pas infaillible, et il est quand même nécessaire de déjà  savoir gérer la mémoire
    • la notation pointée n'est pas naturelle en ObjC
    • on a toujours ce compromis entre les objets et les types C.


    J'ai envie de dire que si le but est qu'Objective-C fasse la même chose que Ruby, alors qu'Apple choisisse Ruby.
  • AliGatorAliGator Membre, Modérateur
    juillet 2012 modifié #39
    Je viens de rendre public une catégorie de mon cru qui reprend le principe des switch/case sur les objets, mais en utilisant un nombre variable d'arguments (plutôt qu'une construction de méthode et invocation au runtime comme l'implémentation d'objcswitch présenté plus haut dans ce sujet).



    Cela permet donc d'éviter les warnings à  la compilation, tout en gardant un code propre et simple à  lire (et en plus ça évite de jouer avec le runtime et d'avoir à  construire une NSInvocation à  la volée et tout) :


    [someString switchCase:<br />
      @&quot;value1&quot;, ^{ NSLog(@&quot;The string someString is equal to value1&#33;&quot;); },<br />
      @&quot;value2&quot;, ^{ NSLog(@&quot;The string someString is equal to value2&#33;&quot;); },<br />
      @&quot;&quot;,	   ^{ NSLog(@&quot;The string someString is empty&#33;&quot;); },<br />
      nil];<br />
    
    On peut aussi demander d'utiliser un autre selecteur que isEqual: ([font=courier new,courier,monospace]switchCaseUsingComparisonSelector:[/font]) ainsi que gérer le cas "[font=courier new,courier,monospace]default:[/font]" au besoin, grâce à  la valeur de retour (voir le README pour les détails et exemples)



    C'est par ici !
  • Je m'en souviens qu'elle t'avais bien plu cette classe , mais ta version va être encore plus sympa à  utiliser je pense, congrats!
  • JegnuXJegnuX Membre
    juillet 2012 modifié #41
    Euh... Sinon pour pas avoir les warning avec la lib de l'autre monsieur là ... Dans la catégorie sur NSObject il suffit de remplacer
    - (ObjcSwitch *) switch;
    


    par
    - (id) switch;
    


    et normalement le compilateur ne dit plus rien image/smile.png' class='bbc_emoticon' alt=':)' />



    Désolé de me réveiller à  peine, mais j'ai eu un cas similaire récemment et j'ai résolu ce problème de warning très simplement comme ça. image/biggrin.png' class='bbc_emoticon' alt=':D' />
  • AliGatorAliGator Membre, Modérateur
    juillet 2012 modifié #42
    Je pensais à  un truc (pas encore testé, j'ai pas récupéré Xcode 4.4 encore)... avec les object literals du nouveau compilateur et le Modern Objective-C, y'a moyen de faire des trucs de fou, notament un ObjCSwitch-like sans avoir une catégorie additionnelle pour gérer ce cas comme j'ai fait, non ?



    En effet, l'idée est de créer un NSDictionary qui utilise comme clé les valeurs possibles, et comme valeur associée le bloc à  exécuter.

    L'implémentation du "switch sur objet" serait alors de simplement récupérer le bon bloc depuis le dictionaire avec objectForKey (ou un bloc par défaut si objectForKey retourne nil) et de l'exécuter (après l'avoir casté).




    #define objcswitch(variableToTest, casesDict, defaultBlock) \<br />
      ((dispatch_block_t)[casesDict[variableToTest]]?:defaultBlock)()<br />
    <br />
    NSString* lang = @&quot;en&quot;;<br />
    <br />
    objcswitch(lang, @{<br />
      @&quot;en&quot; : ^{ NSLog(@&quot;Hello &#33;&quot;; },<br />
      @&quot;fr&quot; : ^{ NSLog(@&quot;Bonjour&quot;; },<br />
      @&quot;es&quot; : ^{ NSLog(@&quot;Ola&quot;; }<br />
    }, ^{ NSLog(@&quot;Unknown language.&quot;); } )
    
    Je vous l'accorde, la syntaxe n'est pas forcément sexy, mais ça devrait marcher image/wink.png' class='bbc_emoticon' alt=';)' />



    De façon décomposée, pour mieux comprendre si ça vous aide, ça donnerait :
    NSDictionary* cases = @{<br />
      @&quot;en&quot; : ^{ NSLog(@&quot;Hello &#33;&quot;; },<br />
      @&quot;fr&quot; : ^{ NSLog(@&quot;Bonjour&quot;; },<br />
      @&quot;es&quot; : ^{ NSLog(@&quot;Ola&quot;; }<br />
    };<br />
    dispatch_block_t defaultCase = ^{ NSLog(@&quot;Unknown language.&quot;); };<br />
    <br />
    dispatch_block_t matchCase = cases[lang]; // récupérer le bloc correspondant à  lang<br />
    if (matchCase == nil) matchCase = defaultCase; // si aucun cas trouvé, utiliser defaultCase<br />
    matchCase(); // exécuter ledit block
    
    Bon ce ne sont que des éléments de réflexion, mais avec la syntaxe @{ key: value, key2:value2 } des dictionary ça peut permettre de faire des trucs puissants quand même !



    PS : La macro écrite ainsi marche aussi avec les tableaux indexés, vu que la syntaxe [] appelle marche sur les dicos et les arrays !
    objcswitch(1, @[<br />
      ^{ NSLog(@&quot;Valeur 0 &#33;&quot;; },<br />
      ^{ NSLog(@&quot;Valeur 1&quot;; },<br />
      ^{ NSLog(@&quot;Valeur 2&quot;; }<br />
    ], ^{ NSLog(@&quot;Valeur non traitée.&quot;); } )
    
  • Ah oui c'est pas sexy mais c'est très puissant. J'adore !
  • AliGatorAliGator Membre, Modérateur
    Xcode 4.4 Téléchargé, code testé et approuvé :
    #if __has_feature(objc_dictionary_literals)<br />
    <br />
        objcswitch(lang, @{<br />
                  @&quot;en&quot;: ^{ NSLog(@&quot;Hello &#33;&quot;); },<br />
                  @&quot;fr&quot;: ^{ NSLog(@&quot;Salut &#33;&quot;); },<br />
                  @&quot;es&quot;: ^{ NSLog(@&quot;Ola &#33;&quot;); }<br />
                  },<br />
                   ^{ NSLog(@&quot;Default Case&quot;); }<br />
                   );<br />
    <br />
    #endif
    
    Voilà  comment j'ai écrit la fonction objcswitch, sous forme de fonction plutôt que de macro d'ailleurs car plus lisible, permet de faire du type-checking, et permet surtout d'éviter que le compilateur s'emmêle les pinceaux avec les virgules dans les paramètres :
    void objcswitch(id test, NSDictionary* cases, dispatch_block_t defaultBlock)<br />
    {<br />
        dispatch_block_t matchingBlock = [cases objectForKey:test];<br />
        if (&#33;matchingBlock) matchingBlock = defaultBlock;<br />
        if (matchingBlock) matchingBlock();<br />
    };
    
  • psychoh13psychoh13 Mothership Developer Membre
    juillet 2012 modifié #45
    ARC n'aime pas du tout qu'on utilise des méthodes qui ne sont pas déclarer donc tu as besoin de déclarer autant de méthodes qu'il y a de cas:
    <br />
    @interface NSObject ()<br />
    <br />
    [font=Menlo]- ([color=#0433ff]void[/color])[color=#0433ff]case[/color]:_:_ [color=#0433ff]default[/color]:_;[/font]<br />
    <br />
    [font=Menlo]- ([color=#0433ff]void[/color])[color=#0433ff]case[/color]:_:_ [color=#0433ff]case[/color]:_:_ [color=#0433ff]default[/color]:_;[/font]<br />
    <br />
    [font=Menlo]- ([color=#0433ff]void[/color])[color=#0433ff]case[/color]:_:_ [color=#0433ff]case[/color]:_:_ [color=#0433ff]case[/color]:_:_ [color=#0433ff]default[/color]:_;[/font]<br />
    <br />
    [font=Menlo]- ([color=#0433ff]void[/color])[color=#0433ff]case[/color]:_:_ [color=#0433ff]case[/color]:_:_ [color=#0433ff]case[/color]:_:_ [color=#0433ff]case[/color]:_:_ [color=#0433ff]default[/color]:_;[/font]<br />
    [font=Menlo]@end[/font]<br />
    [font=Menlo]
    
    [/font]



    Et apparemment le projet fait exactement ça en faisant un #include qui définit pas moins de 32 cas... image/biggrin.png' class='bbc_emoticon' alt=':D' />
  • psychoh13psychoh13 Mothership Developer Membre
    Il y a quelques années j'avais écrit quelque chose de similaire pour d'autres constructions provenant de SmallTalk: https://gist.github.com/239363
  • psychoh13psychoh13 Mothership Developer Membre
    Au passage, je n'ai absolument rien contre les nouvelles syntaxes ajoutées par Apple, ça va rendre le code plus rapide à  écrire et plus simple à  lire, certes ce sera difficile au début mais on s'habitue à  tout.



    Quant à  ARC, je ne pense pas que ça rende la tâche plus facile pour les nouveaux arrivants, je pense même que ça peut la rendre plus difficile. Tu dois toujours faire attention à  ce que tu écris, tu dois penser en terme de graphes d'objets, et tu dois quand même te rappeler des règles.



    En revanche, c'est certainement une grande amélioration pour les développeurs qui comprennent déjà  le fonctionnement de la gestion de mémoire. Ce système rend les programmes plus efficaces et plus stables, les erreurs de gestions de mémoires sont les plus fréquente dans ce langage et c'est une bonne chose que de simplifier cette tâche.
  • AliGatorAliGator Membre, Modérateur
    juillet 2012 modifié #48
    'psychoh13' a écrit:


    ARC n'aime pas du tout qu'on utilise des méthodes qui ne sont pas déclarer donc tu as besoin de déclarer autant de méthodes qu'il y a de cas
    Oui c'est pour ça que je n'aime pas trop la première version de ObjcSwitch de Nicolas Bouilleaud, car l'idée est super bien, c'est astucieux... mais sans la déclaration explicite des prototypes on a forcément plein de warnings image/sad.png' class='bbc_emoticon' alt=':(' />

    D'où ma solution à  moi d'ObjcSwitch qui gère ça avec un nombre variable d'arguments, évitant les warnings et évitant que le compilo gueule. Ou ma solution alternative utilisant la nouvelle syntaxe Modern Objective-C (dictionary literals). Au moins y'a pas le soucis avec le compilo dans ces 2 cas. Certes on n'a pas la syntaxe "case::" mais bon
  • psychoh13psychoh13 Mothership Developer Membre
    'AliGator' a écrit:


    Oui c'est pour ça que je n'aime pas trop la première version de ObjcSwitch de Nicolas Bouilleaud, car l'idée est bien mais sans la déclaration explicite des prototypes on a forcément plein de warnings.

    D'où ma solution à  moi d'ObjcSwitch qui gère ça avec un nombre variable d'arguments, évitant les warnings et évitant que le compilo gueule. Ou ma solution alternative utilisant la nouvelle syntaxe Modern Objective-C (dictionary literals). Au moins y'a pas le soucis avec le compilo dans ces 2 cas.




    Mais la version de Nicolas Bouilleaud déclare ces différentes versions, donc tu ne devrais pas avoir de warning ou d'erreurs.
  • AliGatorAliGator Membre, Modérateur
    Ah ? Pas avec la version que j'avais testé.

    Mais bon ça nécessite beaucoup de déclarations quand même (si tu vas au delà  de 32 ça marche plus, et si tu veux aussi les cas sans "default" ça marche plus non plus ou alors faut les déclarer aussi...) c'est dommage.
  • CéroceCéroce Membre, Modérateur
    Nicolas en avait parlé à  CocoaHeads, et il me semble qu'il utilisait une bidouille avec des #include récursifs pour gérer ce grand nombre de case: potentiels. Par contre, je crois que la bidouille ne fonctionnait qu'avec gcc, peut-être l'a-t-il retirée pour que ça fonctionne avec llvm ?
  • Sinon tout en haut de la page j'ai dis comment faire pour pas avoir tout les warnings hein...
  • AliGatorAliGator Membre, Modérateur
    'Céroce' a écrit:


    Nicolas en avait parlé à  CocoaHeads, et il me semble qu'il utilisait une bidouille avec des #include récursifs pour gérer ce grand nombre de case: potentiels. Par contre, je crois que la bidouille ne fonctionnait qu'avec gcc, peut-être l'a-t-il retirée pour que ça fonctionne avec llvm ?
    En effet je suis allé voir, il utilise la macro __INCLUDE_LEVEL__.

    Il se trouve que je suis bouquiner récemment le site de clang et toutes les extensions et macros qu'il supporte (d'ailleurs j'ai découvert des syntaxes puissantes que je ne connaissais pas), et je n'ai pas souvenir d'avoir vu cette macro dans LLVM ?
  • 'AliGator' a écrit:
    d'ailleurs j'ai découvert des syntaxes puissantes que je ne connaissais pas




    Fait péter ! image/tongue.png' class='bbc_emoticon' alt=':P' />
  • AliGatorAliGator Membre, Modérateur
    Lol nan mais c'est des syntaxes C, pas forcément intéressantes en ObjC, mais pour initialiser des tableaux C ça peut être utile.
    // Initialiser un tableau C d&#39;entiers avec zéro partout sauf pour les valeurs de 10 à  20 et 50 à  80<br />
    int vals[100] = { [10 ... 20] = 5, [50 ... 80] = 12 };<br />
    // Initialiser un tableau de 26 CGPoints, les 10 premiers ont un x=5 et un y=18, les 10 suivants ont un x=12 et un y aussi à  18, les 6 derniers valent (2,8)<br />
    CGPoint points[] = { [0 ... 9].x = 5, [10 ... 19].x = 12, [0 ... 19].y = 18, [20 ... 25] = { .x = 2, .y = 8 };
    
  • AliGatorAliGator Membre, Modérateur
    Au fait, pour référence, pour pouvoir supporter la syntaxe "Objective-C Subscripting" sur NSArray et NSDictionary (c'est à  dire pouvoir écrire v = tab[5], tab[5] = v, v = dico[@toto] et dico[@toto] = v) même sous iOS avant iOS6, je cross-référence mon post fait dans le sujet d'à  côté :

    http://forum.cocoacafe.fr/topic/9374-decouverte-syntaxe-simplifiee-nsarray/page__view__findpost__p__90311



    Il suffit en fait de déclarer les méthodes manquantes (méthodes définies dans le SDK de iOS6 mais pas dans les versions d'avant, forcément) pour que ça marche tout seul. Même pas besoin d'ajouter l'implémentation semble-t-il, car le compilo le ajoute au Runtime de ce que j'ai pu lire ! (La preuve il ne se plaint même pas ni ne crash)
Connectez-vous ou Inscrivez-vous pour répondre.