iOS: Utilisation de self et underscore (_) avec variable

Dupliquer possible:
Comment fonctionne un trait de soulignement devant une variable dans une class d'objective-c de cacao?

J'ai été très confus avec l'utilisation de self ou de underscore avec un nom de variable après l'avoir synthétisé comme ci-dessous:

In .h file: @property(nonatomic, strong) NSMutableArray *users; In .m file: @synthesize users = _users; 

Basé sur mes compréhensions quand j'utilise self.users, OS s'assurera de libérer la memory précédemment allouée dans la méthode set donc nous n'avons pas besoin de faire attention explicitement.

_users est une variable d'instance pour les users et devrait normalement être utilisée lors de l'access à la variable users. Si j'utilise _users pour changer sa valeur, il ne triggersra pas le délégué KVO qui ne notifiera pas une class en observant la modification de la valeur par les users.

De plus, self.users permet de différencier des variables factices dans le nom de la méthode comme ci-dessous,

 - (void)assignUsers:(NSMutableArray*)users { self.users = users; } 

Quelqu'un pourrait-il me dire s'il y a quelque chose que j'ai compris faux ou manquant en utilisant _users ou self.users. Merci.

Je pense qu'il est utile de considérer comment les propriétés sont (ou pourraient être) implémentées par le compilateur.

Lorsque vous écrivez self.users = array; le compilateur traduit ceci en [self setUsers:array]; Lorsque vous écrivez array = self.users; le compilateur traduit ceci en array = [self users];

@synthesize ajoute un ivar à votre object ( sauf si vous l'avez ajouté vous-même ), et implémente les methods -setUsers: et -setUsers: accessor pour vous ( sauf si vous fournissez la vôtre )

Si vous utilisez ARC , -setUsers: ressemblera à -setUsers: :

 - (void)setUsers:(NSArray *)users { _users = users; // ARC takes care of retaining and release the _users ivar } 

Si vous utilisez MRC (ie ARC n'est pas activé), -setUsers: ressemblera à quelque chose comme *:

 - (void)setUsers:(NSArray *)users { [users retain]; [_users release]; _users = users; } 

* – Notez qu'il s'agit d'une implémentation simplifiée et non atomique de -setUsers:

Lorsque vous utilisez les self.users , vous accédez à la propriété via le setter ou le getter.

lorsque vous utilisez les _users , vous accédez directement à la propriété sans passer par le setter ou le getter.


voici une bonne démonstration de celui-ci:

 - (void)setUsers:(id)users { self.users = users; // WRONG : it causes infinite loop (and crash), because inside the setter you are trying to reach the property via setter } 

et

 - (void)setUsers:(id)users { _users = users; // GOOD : set your property correctly } 

C'est aussi le cas dans le cas du getter.


à propos de la gestion de base de la memory (en cas de MRR ou ARC ): l'iOS libérera l'object s'il n'y a plus de pointeur fort qui le maintient en vie , peu importe comment vous libérez le pointeur des objects.

Oui, c'est à peu près correct. Quelques points mineurs:

iOS ne libère pas automatiquement un object simplement parce que vous utilisez la notation par points. Il libère un object lorsque la propriété est déclarée comme copy ou retain (ou strong dans ARC). Si, par exemple, vous utilisez un code non-ARC et que la propriété est déclarée comme assign , elle ne libérera pas l'object.

Avec la dernière version de la string d'outils développeur (Xcode 4.4+), vous n'avez plus besoin de synthétiser manuellement les propriétés – elles sont automatiquement synthétisées (avec le trait de soulignement principal).