Comment fonctionne un soulignement devant une variable dans une classe cacao-objective-c?

J’ai vu dans quelques exemples d’iPhone que les atsortingbuts utilisaient un trait de soulignement _ devant la variable. Est-ce que quelqu’un sait ce que cela signifie? Ou comment ça marche?

Un fichier d’interface que j’utilise ressemble à:

@interface MissionCell : UITableViewCell { Mission *_mission; UILabel *_missionName; } @property (nonatomic, retain) UILabel *missionName; - (Mission *)mission; 

Je ne sais pas exactement ce que ce qui précède, mais lorsque j’essaie de définir le nom de la mission comme suit:

 aMission.missionName = missionName; 

Je reçois l’erreur:

demande de membre ‘missionName’ dans quelque chose qui n’est ni une structure ni un syndicat

Si vous utilisez le préfixe de soulignement pour vos ivars (qui n’est rien d’autre qu’une convention commune, mais une convention utile), vous devez faire 1 chose supplémentaire pour que l’accesseur généré automatiquement (pour la propriété) sache quelle ivar utiliser. Plus précisément, dans votre fichier d’implémentation, votre synthesize devrait ressembler à ceci:

 @synthesize missionName = _missionName; 

Plus génériquement, c’est:

 @synthesize propertyName = _ivarName; 

C’est juste une convention pour la lisibilité, il ne fait rien de spécial pour le compilateur. Vous verrez que les gens l’utilisent sur des variables d’instance privées et des noms de méthode. Apple recommande en fait de ne pas utiliser le trait de soulignement (si vous ne faites pas attention, vous pouvez écraser quelque chose dans votre superclasse), mais vous ne devriez pas vous plaindre d’ignorer ce conseil. 🙂

Le seul but utile que j’ai vu est de différencier les variables locales et les variables membres comme indiqué ci-dessus, mais ce n’est pas une convention nécessaire. Associé à un @property, il augmente la verbosité des instructions de synthèse – @synthesize missionName = _missionName; et est moche partout.

Au lieu d’utiliser le trait de soulignement, utilisez simplement des noms de variables descriptives dans les méthodes qui n’entrent pas en conflit. Quand ils doivent être en conflit, le nom de la variable dans la méthode doit subir un trait de soulignement, pas la variable membre qui peut être utilisée par plusieurs méthodes . Le seul endroit commun utile est un setter ou une méthode init. En outre, l’énoncé @synthesize sera plus concis.

 -(void)setMySsortingng:(NSSsortingng*)_mySsortingng { mySsortingng = _mySsortingng; } 

Edit: Avec la dernière fonction de compilation de l’auto-synthèse, j’utilise maintenant le soulignement pour l’ivar (dans les rares occasions où j’ai besoin d’utiliser un ivar pour correspondre à ce que fait l’auto-synthèse).

Cela ne veut rien dire, c’est juste une convention que certaines personnes utilisent pour différencier les variables membres des variables locales.

En ce qui concerne l’erreur, il semble que aMission ait le mauvais type. Qu’est-ce que c’est sa déclaration?

Ceci est uniquement pour la convention de nommage des propriétés de synthèse.

Lorsque vous synthétisez des variables dans le fichier .m, Xcode vous fournira automatiquement des informations variables.

Avoir un trait de soulignement permet non seulement de résoudre vos ivars sans recourir à la syntaxe self.member, mais cela rend votre code plus lisible car vous savez quand une variable est un ivar (à cause de son préfixe de soulignement) ou un argument de membre (pas de soulignement). ).

Exemple:

 - (void) displayImage: (UIImage *) image { if (image != nil) { // Display the passed image... [_imageView setImage: image]; } else { // fall back on the default image... [_imageView setImage: _image]; } } 

Cela semble être l’élément “maître” pour les questions sur self.variableName vs _variablename. Ce qui m’a jeté en boucle, c’est que dans le .h, j’avais:

 ... @interface myClass : parentClass { className *variableName; // Note lack of _ } @property (strong, nonatomic) className *variableName; ... 

Cela conduit à self.variableName et _variableName étant deux variables distinctes dans le .m. Ce dont j’avais besoin était:

 ... @interface myClass : parentClass { className *_variableName; // Note presence of _ } @property (strong, nonatomic) className *variableName; ... 

Ensuite, dans la classe ‘.m, self.variableName et _variableName sont équivalents.

Ce que je ne comprends toujours pas, c’est pourquoi de nombreux exemples fonctionnent encore, même si ce n’est pas fait.

Rayon

au lieu de souligner, vous pouvez utiliser le nom auto.variable ou vous pouvez synthétiser la variable pour utiliser la variable ou la sortie sans trait de soulignement.

Manquer les autres réponses est que l’utilisation de _variable vous empêche de taper par _variable des variable et d’accéder à la propriété ivar plutôt qu’à la propriété (présumée prévue).

Le compilateur vous obligera à utiliser soit self.variable ou _variable . L’utilisation de traits de soulignement rend impossible la saisie de variable , ce qui réduit les erreurs de programmation.

 - (void)fooMethod { // ERROR - "Use of undeclared identifier 'foo', did you mean '_foo'?" foo = @1; // So instead you must specifically choose to use the property or the ivar: // Property self.foo = @1; // Ivar _foo = @1; }