Conventions de nommage des variables d'instance

muqaddarmuqaddar Administrateur
septembre 2011 modifié dans Objective-C, Swift, C, C++ #1
Salut,

Comme certains le savent, j'avais pour habitude d'utiliser des underscores devant toutes mes variables d'instances.
_ivar

Je me suis fait crié dessus plusieurs fois:
- parce que c'est moche
- parce que c'est réservé aux ivars privées apparemment dans les guidelines

Ok, moi je veux bien. Mais quand-même, pouvoir différencier ses ivars des variables de méthodes, c'est quand-même sympa.

En plus, actuellement ça oblige à  renommer les variables de méthodes pour que le compilateur s'y retrouve. C'est au moins aussi moche d'écrire une variable de méthode aVar ou theVar que d'avoir une variable d'instance _var.  :P

Réponses

  • iSofTomiSofTom Membre
    07:12 modifié #2
    Personnellement j'ai également des conventions de nommage pour mes variables d'instance.
    Mais pour ne pas avoir de conflit avec les variables d'instances d'Apple, elles sont nommées myVar_ .
  • SmySmy Membre
    07:12 modifié #3
    Je suis aussi en _var pour les ivar et en @synthesize var = _var;

    Et je préfère ne pas respecter les guidelines, pour le coup...
  • BunoBuno Membre
    07:12 modifié #4
    Hello,
    Moi, j'adopte la même convention que Moonlight.
  • iSofTomiSofTom Membre
    07:12 modifié #5
    dans 1317124848:

    Hello,
    Moi, j'adopte la même convention que Moonlight.

    hé hé, heureusement  ;)
  • AliGatorAliGator Membre, Modérateur
    07:12 modifié #6
    Ce que l'on trouve moche et pas conventionnel dans tes nommages Alex c'était les propriétés avec des underscores. Les ivars avec des underscores, à  la limite, ça va (officiellement c'est sensé être réservé à  Apple, mais en pratique tout le monde les utilise)

    Perso dorénavant :
    • Si je déclare une @property, je ne déclare plus d'ivars (vive le Modern Runtime), et je ne leur met jamais d'underscore
    • Si je déclare une ivar, c'est parce que je ne déclare pas de @property et veux vraiment gérer ma mémoire manuellement. Et dans ce cas uniquement je mets des underscores au début. Et du coup j'accède à  ma variable via "_mavar = ..." et forcément jamais "self._mavar = ..." (seule exception, si j'ai une ivar dans une classe et que je veux y accéder dans les sous-classes, obligé de faire "self->_mavar" et ça me pique les yeux. Mais j'ai rarement à  le faire c'est vraiment marginal et cas un peu particulier que vous n'avez même peut-être jamais rencontré vous-même)
    • Ceci dit c'est de plus en plus rare que j'ai à  utiliser des ivars. A la limite si je ne veux pas qu'une @property soit dans l'API publique, on doit pouvoir la mettre dans une class extension, donc dans le "@interface MaClasse()" du .m
    • Si j'ai vraiment une ivar avec un nom commençant par un underscore et une @property associée (parce que je suis sur le Legacy Runtime ce qui ne peut être le cas que si je développe pour MacOSX 32 bits), lors de mon @synthesize je l'associe à  une @property sans underscore.
    • Récemment je prend de plus en plus l'habitude de mettre mes @synthesize à  la fin de mon code source (sauf car particulier), et non plus au début. Avantage : comme je ne déclare que la @property sans l'ivar associée, et que c'est le compilo qui la crée au moment du @synthesize, il m'est impossible d'écrire par mégarde dans mon code [tt]toto = x;[/tt] au lieu de [tt]self.toto = x[/tt] puisque la ivar toto n'existe pas encore et ne sera synthétisée qu'à  la fin de l'unité de compilation. Donc comme ça je suis sûr de passer par les accesseurs des propriétés et de pas faire de boulette de gestion mémoire.
  • mpergandmpergand Membre
    07:12 modifié #7
    Salut à  tous,

    Généralement, j'utilise l'underscore pour le C++
    Pour Cocoa, j'utilise deux préfixes:
      o pour les outlets
      i  pour les variables nécessitant un release

    ainsi, je peux vérifier facilement qu'il ne manque rien dans la méthode dealloc.

    Maintenant, pour des projets plus complexes, mélangeant Cocoa, C++, CoreFoundation ...,
    j'ai étendu ce principe aux différents types de variables rencontrées:

    m -> malloc, nécessite un free
    n -> new, nécessite un delete
    i -> retain, nécessite un release (cocoa)
    r -> retain, nécessite un release (coreFoundation)
    a -> allocation automatique
    v -> variable simple
    b -> boolean
    s -> static

    <br />class CADevice {<br />																<br />				AudioDeviceID	vDeviceID;<br />				CFStringRef		rName;<br />				CFStringRef		rUID;<br />				bool			bInput;				// has input<br />				bool			bOutput;			// has output<br />
    

    Donc ici, je sais que je dois faire un CFRelease sur les deux vars avec le préfixe r dans le destructeur.

    NB:
    Je n'utilise pas le "modern runtime" car mon système principale reste Léopard et Xcode 2.5  :P
    Si Xcode 4 semble prometteur, Lion lui, est bien trop buggé !
    Donc, il est urgent d'attendre  :D
  • muqaddarmuqaddar Administrateur
    07:12 modifié #8
    Merci pour vos avis éclairés.

    Récemment je prend de plus en plus l'habitude de mettre mes @synthesize à  la fin de mon code source (sauf car particulier), et non plus au début. Avantage : comme je ne déclare que la @property sans l'ivar associée, et que c'est le compilo qui la crée au moment du @synthesize, il m'est impossible d'écrire par mégarde dans mon code toto = x; au lieu de self.toto = x puisque la ivar toto n'existe pas encore et ne sera synthétisée qu'à  la fin de l'unité de compilation. Donc comme ça je suis sûr de passer par les accesseurs des propriétés et de pas faire de boulette de gestion mémoire.


    ça, c'est de l'astuce bordel ! 

    Sinon, j'utilise aussi très rarement les ivars sans propriété.
  • CéroceCéroce Membre, Modérateur
    07:12 modifié #9
    dans 1317128384:

    Récemment je prend de plus en plus l'habitude de mettre mes @synthesize à  la fin de mon code source (sauf car particulier), et non plus au début. Avantage : comme je ne déclare que la @property sans l'ivar associée, et que c'est le compilo qui la crée au moment du @synthesize, il m'est impossible d'écrire par mégarde dans mon code [tt]toto = x;[/tt] au lieu de [tt]self.toto = x[/tt] puisque la ivar toto n'existe pas encore et ne sera synthétisée qu'à  la fin de l'unité de compilation. Donc comme ça je suis sûr de passer par les accesseurs des propriétés et de pas faire de boulette de gestion mémoire.


    Je t'avoue que ça me laisse perplexe: les compilateurs C travaillent en deux passes: la première résout les symboles et la seconde génère le code machine. ça voudrait dire que la résolution des @synthesize est faite lors de la seconde passe !!!
  • AliGatorAliGator Membre, Modérateur
    07:12 modifié #10
    @Ceroce : oui ça m'a étonné aussi, mais c'est qqch que j'ai remarqué en pratique.

    C'est comme la nécessité (depuis peu ? Dépend des options de compilation ?) si on veut accéder à  une ivar d'une classe parente, de devoir faire self->var au lieu de var. Avant ça marchait bien, et ça m'est arrivé de modifier un code source auquel je n'avais pas touché depuis des lustres et du coup comme je l'ai modifié il a recompilé le code... et m'a sorti des erreurs à  ce sujet. Pas compris tout de suite ce qui lui prenait et à  quoi elles correspondaient !

    @interface Parent : NSObject {<br />&nbsp; int _ivar;<br />}<br />@end<br /><br />@implementation Parent<br />@end<br /><br />///////////////////////////<br /><br />@interface Enfant : Parent<br />-(void)testIVar;<br />@end<br /><br /><br />@implementation Enfant<br />-(void)testIVar {<br />&nbsp; int v1 = _ivar; // avant ça passait, maintenant (depuis quand je ne saurais dire) ça ne passe plus<br />&nbsp; int v2 = self-&gt;_ivar; // accès explicite à  un membre, ça ça passe dans tous les cas.<br />}<br />@end
    
  • septembre 2011 modifié #11
    Y'a pas vraiment besoin de déclarer d'Ivar en fait.

    Moi je fais comme ça:
    <br />@interface Toto : NSObject<br />@property (assign, readonly, getter=isStupid) BOOL stupid;<br />@end<br /><br />@implementation Toto<br />@synthesize stupid = _stupid;<br />@end<br />
    


    Ducoup tu peux très facilement faire la distinction quand tu écris l'implémentation de Toto. Sans pour autant remplir ton .h avec des Ivar de partout
  • AliGatorAliGator Membre, Modérateur
    septembre 2011 modifié #12
    Toi Louka t'as pas lu tout ce que j'ai écrit tout au long de ce thread :D

    J'ai indiqué à  plusieurs reprises que j'étais le premier à  profiter des possibilités du Modern Runtime et que je ne déclarais quasiment plus jamais d'ivars, que c'était super rare que j'en utilise vu que maintenant je mets tout en @property avec auto-synthesize de la backing variable par le compilo.

    Mais y'a des (rares) cas où ça reste plus logique voire incontournable (même si ces cas sont parfois alambiqués), et pour ces très très rares cas, je faisais alors part de la subtilité de la notation [tt]self->var[/tt] qui doit être utilisée dans les sous-classes. Mais comme je l'ai mentionné,
    AliGator a écrit:
    Mais j'ai rarement à  le faire c'est vraiment marginal et cas un peu particulier que vous n'avez même peut-être jamais rencontré vous-même


    Toi, à  mon avis le code de muqaddar t'as tellement piqué les yeux que t'arrives plus à  lire les messages du forum depuis :D
  • muqaddarmuqaddar Administrateur
    07:12 modifié #13
    dans 1317143129:

    Toi, à  mon avis le code de muqaddar t'as tellement piqué les yeux que t'arrives plus à  lire les messages du forum depuis :D


    Je rêve.  >:)
    L'essentiel c'est de s'y retrouver chacun avec son code et ses propres méthodes, mais ça n'empêche pas de demander comment les autres font !
  • 07:12 modifié #14
    dans 1317143129:

    Toi Louka t'as pas lu tout ce que j'ai écrit tout au long de ce thread :D

    J'ai indiqué à  plusieurs reprises que j'étais le premier à  profiter des possibilités du Modern Runtime et que je ne déclarais quasiment plus jamais d'ivars, que c'était super rare que j'en utilise vu que maintenant je mets tout en @property avec auto-synthesize de la backing variable par le compilo.

    Mais y'a des (rares) cas où ça reste plus logique voire incontournable (même si ces cas sont parfois alambiqués), et pour ces très très rares cas, je faisais alors part de la subtilité de la notation [tt]self->var[/tt] qui doit être utilisée dans les sous-classes. Mais comme je l'ai mentionné,
    AliGator a écrit:
    Mais j'ai rarement à  le faire c'est vraiment marginal et cas un peu particulier que vous n'avez même peut-être jamais rencontré vous-même


    Toi, à  mon avis le code de muqaddar t'as tellement piqué les yeux que t'arrives plus à  lire les messages du forum depuis :D


    Désolé j'arrive à  lire que les trucs marqués dans les balises code :D
  • AliGatorAliGator Membre, Modérateur
    07:12 modifié #15
    Note qu'il n'y en avait aucune dans mon précédent message et que tu as réussi à  t'en sortir :D
  • 07:12 modifié #16
    dans 1317149069:

    Note qu'il n'y en avait aucune dans mon précédent message et que tu as réussi à  t'en sortir :D


    C'est parce que tu as écrit "Louka", ça m'interpelle ça aussi  xd
  • BunoBuno Membre
    07:12 modifié #17
    dans 1317145250:

    L'essentiel c'est de s'y retrouver chacun avec son code et ses propres méthodes, mais ça n'empêche pas de demander comment les autres font !

    En généralisant, l'essentiel est d'avoir une convention commune au sein d'une même équipe.
  • 07:12 modifié #18
    Bonjour à  tous,

    On cherche à  uniformiser un peu l'écriture du code Objective-C de notre côté..
    Les habitudes évoluent avec le temps.. Au départ, mes Ivar n'avaient pas d'underscore devant leur nom. Et puis, vint l'objective-C 2.0 avec @property @synthesize.. Depuis je fonctionne comme ceci:

    <br />@interface MyViewController : UIViewController<br /><br />@property (nonatomic, readonly) MyCustomView *customView;<br />@end<br /><br />@implementation MyViewController<br />@synthesize customView = _customView;<br /><br />- (void)loadView<br />{<br />	_customView = .....<br />}<br /><br />@end<br />
    


    Est-ce que ça vous simple correct? J'ai un peu du mal à  passer par des "i_myIvar", je trouve ça abominable d'avoir une lettre en plus dans le nom d'une Ivar. Alors que l'underscore reste très discret. J'évite aussi les double underscore, car je réserve ça à  des méthodes privées.

    Le problème est qu'Apple fait exactement pareil... elle utilise un simple underscore devant ses Ivar, on le voit si, par exemple, vous sous-classez UITableViewCell et que vous déclarez _textLabel. Fort heureusement, il y a une erreur à  la compilation.. Ce qui est une bonne chose. Seulement, je me demande ce qu'il se passera si Apple fait une mise à  jour d'iOS et qu'une classe que j'aurai sous-classé (prenons  UIViewController en exemple comme ci-dessus) contiendrait maintenant une iVar privée "_customView"... L'application serait déjà  compilée et installée sur plusieurs devices, et je ne sais pas comment ça se comportera à  ce moment là .. risque de gros soucis quant au fonctionnement de l'application...

    Ducoup, je suppose que la plupart vont me conseiller un double underscore ou un "i_"... mais j'aimerai un peu connaà®tre votre façon de faire.

    Merci 
  • CéroceCéroce Membre, Modérateur
    07:12 modifié #19
    Personnellement, je ne mets ni préfixe, ni suffixe.
    Le fait de ne pas identifier les variables d'instance ne me gène pas. À vrai dire, je ne me souviens pas d'un cas où j'ai eu un doute.
  • AliGatorAliGator Membre, Modérateur
    07:12 modifié #20
    C'est quoi des variables d'instance ? Lol
    Perso j'en utilise de moins en moins depuis qu'avec le Modern Runtime elles ne sont plus nécessaires.

    Avant je les utilisais encore pour stocker mes données privées (donc pas envie de mettre une @property pour l'exposer) modèle (car tous les IBOutlets par contre passent pas des @property, gestion mémoire oblige) mais même maintenant c'est de plus en plus rare (quitte à  déclarer mon @property dans une Extensions de classe)

    Après les rares fois où je les utilise en effet je mets un underscore en début de nom, au risque certes d'entrer en conflit avec les variables Apple. J'en vois mettre un underscore à  la fin du nom, je trouve ça laid. "i_" ou "m_" j'ai du mal aussi mais je préfèrerai encore ce préfixe à  un underscore en suffixe...
  • octobre 2011 modifié #21
    Le problème c'est que je suis du genre à  aimer différencier les choses...
    Certes, la property "toto" peut être utilisée comme tel, mais ça me choque de faire "toto = ..." dans le code. Et j'évite de faire [self setToto:] à  part si réelle nécessitée.. (mais dans le "setup" d'un composant visuel, je fais direct myIvar = ....)

    Bref, c'est vraiment une question de distinction pure et dure..

    Et puis, cas typique qui me dérange, en admettant que je ne déclare pas de Ivar:
    <br />- (void)setToto:(...<br />
    

    Xcode va proposer l'auto-completion comme suit:
    <br />- (void)setToto:(Toto*)toto<br />{<br /><br />}<br />
    


    Problème... on a "toto" en argument... qui porte le même nom que notre property.
    Ducoup, avec mon @synthesize toto = _toto; je n'ai pas de soucis:
    <br />- (void)setToto:(Toto*)toto<br />{<br />	if(_toto != toto)<br />	{<br />		[_toto release];<br />		_toto = [toto retain];<br />	}<br />}<br />
    


    Alors que sans la Ivar, je suis obligé de renommé l'argument "toto" en "aToto"... merci l'auto-completion.
  • CéroceCéroce Membre, Modérateur
    07:12 modifié #22
    C'est vrai que dans ce cas, j'écris ça à  la place:

    - (void)setToto:(Toto*)newToto
    


    Effectivement, ce serait bien que l'auto-completion le fasse automatiquement, mais peut-être est-ce difficile?
  • 07:12 modifié #23
    J'ai stipulé ça parce que ça venait de me revenir en fait.. voilà  pourquoi j'ai soudainement pris l'habitude de faire @synthesize myIvar = _myIvar...
    À force de faire des composants visuels où il faut la plupart du temps réécrire les setters...
  • SmySmy Membre
    07:12 modifié #24
    Je fais comme toi, ivar en _toto, synthesize en toto = _toto.

    J'ai l'impression que nous avons récemment eu cette discussion.

    [EDIT] Trouvé, c'était là  : http://pommedev.mediabox.fr/frameworks-communs-objective-c/conventions-de-nommage-des-variables-d'instance/
  • AliGatorAliGator Membre, Modérateur
    07:12 modifié #25
    C'est aussi pour ça que :
    1) Je n'accès jamais aux ivar genre [tt]toto[/tt] directement, mais par [tt]self.toto[/tt], sauf
    2) Je mets mes [tt]@synthesize toto;[/tt] à  la fin de mon ".m" comme ça je ne peux pas appeler [tt]toto[/tt] directement vu que le [tt]@synthesize[/tt] n'a pas encore généré l'ivar
    3) Après si je dois vraiment manipuler l'ivar directos oui je mets un [tt]@synthesize toto = _toto;[/tt] et j'utilise du coup [tt]_toto[/tt], mais uniquement dans mes setters/getters, jamais ailleurs.
  • octobre 2011 modifié #26
    dans 1318519676:

    C'est aussi pour ça que :
    1) Je n'accès jamais aux ivar genre [tt]toto[/tt] directement, mais par [tt]self.toto[/tt], sauf
    2) Je mets mes [tt]@synthesize toto;[/tt] à  la fin de mon ".m" comme ça je ne peux pas appeler [tt]toto[/tt] directement vu que le [tt]@synthesize[/tt] n'a pas encore généré l'ivar
    3) Après si je dois vraiment manipuler l'ivar directos oui je mets un [tt]@synthesize toto = _toto;[/tt] et j'utilise du coup [tt]_toto[/tt], mais uniquement dans mes setters/getters, jamais ailleurs.


    Je trouve ça totalement imbitable de toujours devoir faire self.toto... Autant [machin toto] ou machin.toto me dérange pas, mais self.toto ou [self toto] je trouve ça hyper lourd à  force.. et c'est plus long à  l'exécution (bon OK là  c'est de l'ordre du gros CHIPOTAGE :D)


    Après.. je pense que tant que ça ne choque personne.. c'est pas trop grave. Moi ça me dérange pas tant que ça ta méthode, Ali, c'est juste que pour ma part je doute faire ça un jour..

    J'ai déplacé le sujet. (enfin je l'ai fusionné avec l'ancien)
  • muqaddarmuqaddar Administrateur
    07:12 modifié #27
    Au moins quand tu fais self.toto, tu sais que tu vas agir sur une "ivar" via une property... alors que toto tout seul peut être une variable de méthode, ça sert au moins à  ça pour le coup.
Connectez-vous ou Inscrivez-vous pour répondre.