Préfixer les noms de propriété avec un trait de soulignement dans l’objective C

J’ai déjà évité les traits de soulignement dans mes noms de variables, peut-être un vestige de mes jours de Java à l’université. Donc, lorsque je définis une propriété dans l’objective C, c’est ce que je fais naturellement.

// In the header @interface Whatever { NSSsortingng *mySsortingngProperty } @property (nonatomic, copy) NSSsortingng *mySsortingngProperty; // In the implementation @synthesize mySsortingngProperty; 

Mais dans presque tous les exemples, cela se fait comme

 // In the header @interface Whatever { NSSsortingng *_mySsortingngProperty } @property (nonatomic, copy) NSSsortingng *mySsortingngProperty; // In the implementation @synthesize mySsortingngProperty = _mySsortingngProperty; 

Devrais-je surmonter mon aversion pour le soulignement parce que c’est la seule façon de le faire, y a-t-il une bonne raison pour que ce style soit préféré?

Mise à jour: Avec la synthèse automatique des propriétés de nos jours, vous pouvez laisser de côté la synthèse @ et le résultat est le même que si vous aviez utilisé

 @synthesize mySsortingngProperty = _mySsortingngProperty; 

ce qui montre clairement la préférence d’Apple. J’ai depuis appris à cesser de m’inquiéter et à aimer le soulignement.

J’utilise toujours des traits de soulignement. Cela crée une distinction claire entre les variables locales et les variables d’instance. Il évite également les avertissements du compilateur dans les cas suivants:

 @interface MyClass { NSSsortingng *name } @property (nonatomic, copy) NSSsortingng *name; - (id) initWithName:(NSSsortingng *) name; @end @implementation MyClass @synthesize name; // The following method will result in a comstackr warning // (parameter name same as ivar name) - (id) initWithName:(NSSsortingng *) name { if (self = [super init]) { self.name = name; } return self; } @end 

EDIT :

Après avoir enduré les votes faibles et lu les commentaires, laissez-moi essayer de faire ma remarque:

Apple recommande que les ivars portent le même nom que leur propriété. Apple recommande également que les propriétés commencent par une lettre minuscule. Et Apple recommande également que les variables locales commencent par une lettre minuscule.

Maintenant, vous avez un problème, car lorsque vous lisez un morceau de code et que vous voyez une variable utilisée, vous ne pouvez pas dire par la convention de nommage si cette variable est une variable ivar ou locale. Ça craint. La solution consiste à avoir des conventions de dénomination différentes pour les ivars et les variables locales. C’est juste du bon sens.

La façon dont vous implémentez cette convention de dénomination est sans importance. Si vous voulez vraiment, vous pouvez simplement append “_WOOHAHA” aux noms ivar. Je m’en fiche (mais peut-être que d’autres le feront). Le fait est que les gens qui savent ce qu’ils font ont décidé d’utiliser le “préfixe de soulignement” pour les ivars. À mon humble avis, ils ont pris la bonne décision, même si leur propre entreprise recommande autre chose. (les développeurs dont je parle sont ceux qui écrivent les principaux frameworks Apple et les classes .NET Framework)

En fin de compte, la qualité du code est plus importante que de suivre une règle stupide qui n’est même pas suivie par les gens qui la prêchent.


Une autre remarque sur le code que vous avez montré: n’utilisez jamais les propriétés de conservation sur les chaînes. Vous devriez utiliser la copie à la place.

Pour plus d’informations sur la copie / conservation des propriétés, voir:

Propriété NSSsortingng: copier ou conserver?

La convention de dénomination de la variable d’instance préfixée par _ est maintenant clairement indiquée par Apple dans les “Directives de codage pour le cacao”, après la révision du 2012-02-16, avec sa raison.

Assurez-vous que le nom de la variable d’instance décrit de manière concise l’atsortingbut stocké. En règle générale, vous ne devez pas accéder directement aux variables d’instance. Vous devez plutôt utiliser les méthodes d’access (vous accédez directement aux variables d’instance dans les méthodes init et dealloc). Pour aider à signaler cela, préfixez les noms de variables d’instance par un trait de soulignement (_), par exemple:

 @implementation MyClass { BOOL _showsTitle; } 

Si vous synthétisez la variable d’instance à l’aide d’une propriété déclarée, spécifiez le nom de la variable d’instance dans l’instruction @synthesize.

 @implementation MyClass @synthesize showsTitle=_showsTitle; 

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE

La conférence sur iTunes U, iPhone App Development CS193p automne 2011, enseignée par Paul Hegarty à l’université de Stanford, explique également cette convention.

http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255

Je suis conscient que cette question a été posée il y a un certain temps, mais j’ai moi-même eu la même question et je voulais partager mes découvertes.

L’objective actuel d’Objective-C 2.0 est d’utiliser le même nom pour l’ivar que la propriété. Vous pouvez éventuellement assigner un ivar différent dans la déclaration @property, mais le fait que, par défaut, les accesseurs synthétisés pour une propriété accèdent à l’ivar avec le même nom que la propriété indique que c’est le modèle auquel vous devez vous conformer.

Quoi qu’il en soit, comme les objects doivent toujours envoyer des messages à eux-mêmes pour accéder aux propriétés, il est difficile de confondre lorsque vous accédez à une propriété ou lorsque vous accédez directement à son ivar de sauvegarde. plus possible. L’utilisation de la syntaxe de passage de message standard rend l’intention plus explicite, IMO.

 @interface Foo : NSObject { NSNumber *bar; } @property(readwrite, retain) NSNumber * bar @end @implementation Foo @synthesize bar; -(void) baz { NSNumber *numberOne = [NSNumber numberWithInt: 1]; //Both set the value of bar through either the your custom or the synthesized setter method [self setBar:numberOne]; self.bar = numberOne; //Both get the value of bar through your synthesized or your custom accessor method NSNumber *fooBar = [self bar]; fooBar = self.bar; //Both manipulate the bar ivar directly bar = numberOne; fooBar = bar; } @end 

Apple réserve les sélecteurs en commençant par un trait de soulignement pour leurs propres méthodes “privées” et qui incluent les propriétés. Je ne pense pas qu’ils réservent _ pour les noms d’ivar cependant.

Personnellement, j’éviterais d’utiliser le trait de soulignement pour lancer n’importe quel type de nom de variable. C’est une convention opaque. Que se passe-t-il si quelqu’un d’autre utilise un soulignement pour les sections locales et aucun trait de soulignement pour les variables d’instance? Que se passe-t-il si vous omettez accidentellement le trait de soulignement dans une méthode où vous avez un local défini avec le même nom?

Il est préférable de rendre vos noms locaux différents de vos noms ivar. Par exemple, dans un setter, vous pouvez utiliser newName ou neWValue.

C’est purement une question de style.

Je ne sais pas quels exemples utilisent le style ivar souligné. Les exemples officiels d’Apple (par exemple CryptoExercise ) ne préfixent pas les ivars avec _ .

Je soulignerai simplement qu’un nouveau projet de navigation utilisant des données de base utilise par défaut des traits de soulignement et rend les variables privées.

 @interface MyTestAppDelegate : NSObject  { UIWindow *window; UINavigationController *navigationController; @private NSManagedObjectContext *managedObjectContext_; NSManagedObjectModel *managedObjectModel_; NSPersistentStoreCoordinator *persistentStoreCoordinator_; } @interface RootViewController : UITableViewController  { @private NSFetchedResultsController *fetchedResultsController_; NSManagedObjectContext *managedObjectContext_; } 

La partie KVC du moteur d’exécution attend un nom ou un _name ivar lors de l’utilisation de valueForKey: sur un object lorsqu’il ne trouve pas un message pour récupérer cette variable. voir http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html

Si le moteur d’exécution cherche à rechercher _name et la documentation Apple mentionne d’abord _name, il pourrait y avoir une bonne raison à cela. Jetons un coup d’oeil à quelques classes de SDK: UINavigationBar.h cette classe a des soulignements devant tous les ivars, UIView aussi … la liste est longue. Eh bien, peut-être est-ce ainsi que le nouveau SDK iOS brouillé et les bonnes classes NS * ne font pas les choses de cette façon … fausses; ils utilisent également le trait de soulignement dans les fichiers d’en-tête.

Apple utilise le trait de soulignement dans les messages API privés ainsi que dans les ivars. Je ne peux pas comprendre pourquoi leurs exemples ne poussent pas ce comportement en particulier lorsque le runtime dérange de faire coder cette soi-disant “convention de dénomination” dans le chemin de recherche des variables. Ce serait bien de voir une certaine cohérence.

Juste une note, il y a un schéma de nommage ssortingct que vous devez suivre pour être conforme à KVC; Le lien ci-dessus vous aide à vous y conformer pour utiliser cette fonctionnalité pratique du moteur d’exécution.