Switch et NSString

GreensourceGreensource Membre
22:32 modifié dans API AppKit #1
Je remarque que le switch n'apprécie pas les pointeur en tant que "case value", ce que je peut comprendre  :)
Mais alors comment faire un switch sur différente valeur de NSString? Vais-je être réduit a un if else if else if else sans fin?

Réponses

  • 22:32 modifié #2
    Bha tu me diras y'a pas grande différence niveau longueur de code entre un if else et un switch case...
  • GreensourceGreensource Membre
    22:32 modifié #3
    Certe, mais je me disais qu'il existait peut-être une solution que je ne connaissait pas encore ;)
  • 22:32 modifié #4
    dans 1247914282:

    Certe, mais je me disais qu'il existait peut-être une solution que je ne connaissait pas encore ;)


    Heuu pas à  ma connaissance du moins. Mais ça dépend du contexte, et quels sont ces NSString. Quand c'est des NSMenuItem par exemple je m'arrange souvent pour jouer avec les tags.
  • GreensourceGreensource Membre
    22:32 modifié #5
    Là  ce sont des chaà®nes récupérer d'un PList, et je m'en sert pour de initialisation en fonction de celle-ci.
  • 22:32 modifié #6
    dans 1247916478:

    Là  ce sont des chaà®nes récupérer d'un PList, et je m'en sert pour de initialisation en fonction de celle-ci.


    Dans ce cas je te conseille de mettre des @selector dans ton plist à  la place :p
  • GreensourceGreensource Membre
    22:32 modifié #7
    1 - Je savais qu'on pouvais et je ne sai spas comment faire ça.
    2 - Ca risque pas de faire beaucoup de méthode à  implémenter ça?
  • yoannyoann Membre
    22:32 modifié #8
    Tu peut charger un NSDictionary avec tes strings en clef et en valeur un NSNumber que tu converti en int et hop tu as ton switch case sinon
  • GreensourceGreensource Membre
    22:32 modifié #9
    Ouais mais du coup autant mettre des NSNumber direct dans le PList.
    Je crois que je vais rester sur le if else du coup.
  • NoNo Membre
    juillet 2009 modifié #10
    Tu peux utiliser une structure switch avec les chaines :

    <br />switch ([taChaine hash])<br />{<br />  case [@&quot;cas n°1&quot; hash] :<br />    // traitement cas 1<br />    break;<br /><br />  case [@&quot;cas n°2&quot; hash] :<br />    // traitement cas 2<br />    break;<br /><br />  default:<br />    // traitement autres cas<br />}<br />
    

    mias il faut vérifier (mes cours de C sont loin) si le case accepte des fonctions à  la place des litéraux.

    Sinon, reste les séries de if non-imbriqués simulant le switch :

    <br />if ([taChaine isEqual:@&quot;cas n°1&quot;])<br />{<br />  // traitement cas 1<br />}<br /><br />else if ([taChaine isEqual:@&quot;cas n°2&quot;])<br />{<br />  // traitement cas 2<br />}<br /><br />else<br />{<br />  // traitement autres cas<br />}<br />
    
  • GreensourceGreensource Membre
    22:32 modifié #11
    J'ai finalement utilisé ta deuxième solution en effet.
    Mais pourquoi le switch ne s'adapte pas au monde de l'objet, c'est étrange quand même? Avec le isEqual de NSObject ya moyen non?
  • CéroceCéroce Membre, Modérateur
    22:32 modifié #12
    dans 1248083362:

    mias il faut vérifier (mes cours de C sont loin) si le case accepte des fonctions à  la place des litéraux.


    Non, les case n'acceptent que des entiers.
  • CéroceCéroce Membre, Modérateur
    22:32 modifié #13
    dans 1248083559:

    Mais pourquoi le switch ne s'adapte pas au monde de l'objet, c'est étrange quand même? Avec le isEqual de NSObject ya moyen non?


    Parce qu'ObjC n'est pas un langage objet pur. Essaie de programmer un peu en Python, par exemple, et un tas d'aspects d'ObjC te paraà®tront fort rétrogrades.

    ObjC est un compromis entre la vitesse d'exécution et la facilité d'écriture. C'est un langage bien adapté aux performances des machines actuelles, mais ce n'est pas un langage d'avenir.
  • mpergandmpergand Membre
    juillet 2009 modifié #14
    Le switch c'est du C, donc pas d'objet.

    La valeur testée doit être de type intégral et les cases des constantes.

    Il fut un temps où ça devait être uniquement du int.

    Kernighan & Ritchie  :

    In the first edition of this book, the controlling expression of switch, and the case constants, were
    required to have int type. 



    Pour comparer des strings, il vaut mieux utiliser isEqualToString
    Special Considerations
    When you know both objects are strings, this method is a faster way to check equality than isEqual

  • AliGatorAliGator Membre, Modérateur
    22:32 modifié #15
    A mon avis le switch a été créé à  la base pour refléter le cas typique de la façon de faire ce genre de comparaison en assembleur :
    1) Pour comparer 2 entiers grosso modo, on charge la 1ère valeur dans un registre, la seconde valeur dans un second régistre, on fait la différence et on choisit une branche ou l'autre (on fait un saut dans le programme ou pas) si ladite différence est zéro (genre instruction JNZ, Jump If Not Zero)
    2) Du coup pour comparer une valeur particulière à  différentes constantes, ce qui est le cas du switch/case, on charge la valeur de notre variable dans un registre, et ensuite on a plus qu'à  enchaà®ner {chargement de la constante, et test si la différence vaut zéro ou non} pour chaque constante avec laquelle on veut comparer.

    Pour moi le switch est le reflet du fait que si on compare nos constantes toujours à  la même variable, autant ne charger cette variable dans le registre qu'une seule fois. Historiquement du moins ça me semblerait logique que ça hérite de ça.

    Maintenant, entre toutes les optimisations des compilateurs et améliorations des CPU et architectures matérielles, ce n'est plus forcément d'actualité. Mais ça justifie l'existence du switch... et surtout la raison pour laquelle ça ne marche que sur des entiers.

    Si tu veux comparer des objets en utilisant des fonctions (genre isEqualToString), le process utilisé n'implique plus du tout les mêmes mécanismes au final sous le capot (et donc côté code assembleur) et n'offre plus le même fonctionnement que celui décrit (donc l'avantage de chargement unique de la valeur dans un des registres)... donc le switch n'est plus adapté du tout.


    Sinon pour la solution d'utiliser le hash, c'est pas idiot... Sauf que le hash n'est pas forcément unique, seulement pseudo-unique : le principe d'un hash c'est en général que 2 objets identiques auront le même hash, mais que 2 objets qui ont le même hash ont juste de fortes chances du coup d'être identiques, mais ne le sont pas non plus forcément à  100%. Ca permet d'accélérer les comparaisons grace à  la probabilité plus forte que les objets soient identiques avec une comparaison rapide (car mettant en oeuvre des int et non des objets), mais une fois qu'on a vu que les hash étaient identiques, il faut qd mm vérifier que les objets le sont aussi.
  • schlumschlum Membre
    22:32 modifié #16
    Le coup du hash ne fonctionnera pas, car une étiquette de "case" doit être une constante...
  • psychoh13psychoh13 Mothership Developer Membre
    22:32 modifié #17
    ObjC est un langage objet pur, mais il est basé sur le C, et il ne modifie pas son comportement, contrairement au C++. Il n'y a donc pas de polymorphisme ou de surcharge des opérateurs et autres structures de contrôle.
Connectez-vous ou Inscrivez-vous pour répondre.