2011-09-14 4 views
-2

Possible en double:
Prefixing property names with an underscore in Objective Cmise en forme

Souvent, quand je télécharger objectif un exemple de code source c, je vois ce qui suit:

Dans l'interface MyClass,. h fichier:

MyObject *_myObject; 

Dans la mise en œuvre de MyClass, fichier .m:

@interface MyClass() 

@property (nonatomic, retain) MyObject *myObject; 

@end 

@implementation MyClass 

@synthesize myObject = _myObject; 

... 

Quelqu'un peut-il me expliquer pourquoi je ne déclarer que MyObject * myObject dans le fichier .h, et comprennent également la déclaration de droit de propriété dans le .h fichier? Pourquoi déclarent-ils * _myObject? Et qu'est-ce que cela signifie quand vous avez @synthesize varA = varB?

Merci! donc tout ce que nous avons

+0

C'est '@ synthesize', pas' @ synthesis'. –

Répondre

3

Il y a deux choses distinctes qui se déroulent:

  1. Accesseur privé: la propriété est déclarée dans une catégorie appelée sans nom une « extension » de sorte qu'il est privé et non visible à l'extérieur des classes.
  2. Un Ivar des noms différents. Le Ivar sauvegarde la propriété est nommé quelque chose de différent de la propriété elle-même * C'est ce que @synthesize myObject = _myObject; signifie: cela signifie synthétisent la propriété myObject, mais font définir la variable _myObject, non myObject (qui n'existe pas, comme vous l'avez remarqué).

* Il y a plusieurs raisons pour ce faire, impliquant généralement d'éviter la confusion entre [self myObject] et myObject (en faisant ce dernier existe pas).

+0

J'aime ça. Bonne explication concise du but réel du code plutôt que de ce que signifient les lignes individuelles. – Chuck

+0

Est-ce une bonne habitude de toujours faire un ivar différemment nommé quand vous voulez que l'ivar soit aussi une propriété, pour vous forcer à toujours accéder à la propriété via les méthodes getter/setter synthétisées plutôt que directement? –

+1

C'est une bonne habitude de (presque) toujours accéder à la propriété via les accesseurs, mais personnellement, je préfère juste le faire, et laisser mes noms de variables seuls. Je ne me vois jamais confondre accidentellement '[self myObject]' et 'myObject'. – andyvn22

0

Même si Why does C++ need a separate header file? est C++, ce qui peut être appliqué à l'objectif-c trop

A propos @synthesize

La directive @synthesize génère automatiquement les setters et getters pour nous, implémenter pour cette classe est la méthode dealloc .

Les accesseurs ne seront générés que s'ils n'existent pas déjà, alors sentez libre de spécifier @synthesize pour une propriété, puis implémentez votre getter ou setter personnalisé si vous le souhaitez. Le compilateur remplira la méthode manquante.

http://cocoadevcentral.com/d/learn_objectivec/

1
@synthesize /* not @synthesis */ varA = varB; 

ensembles varB comme Ivar pour la propriété varA.

Il n'y a pas de besoin direct pour cela, mais certains préfèrent qu'il soit plus facile de distinguer la propriété et l'ivar. En fait, si la propriété et ivar ont le même nom (ce qui arrive si vous ne spécifiez pas l'ivar "manuellement"), vous pouvez les distinguer par self.: self.xyz est une propriété, alors que xyz (non self.) est la variable correspondante.

J'utilisé pour donner des noms différents à mes Ivars aussi, mais actuellement, je préfère simplement:

@property (retain) NSSomeType *xyz; 

et

@synthesize xyz; 

Et laisser le compilateur prendre en charge le reste.

1

La raison de nommer les ivars différemment des propriétés est que cela rend l'utilisation d'ivar incorrecte très évidente dans le code. Par exemple, considérez la ligne de code suivante:

myObject = [self something]; 

Est-il correct? Eh bien, cela dépend si myObject est une variable ivar ou locale. Si c'est local, c'est presque certainement très bien. Si c'est un ivar, cela pourrait être une fuite et il est très probable qu'il soit également sous-retenu et qu'il s'écrase plus tard. Si Ivars ont des noms spéciaux (comme un underscore final dans le style Google), il est très clair que ceci est incorrect:

myObject_ = [self something]; 

Et il est aussi très clair que cela est correct:

self.myObject = [self something]; 

I Personnellement, préférez le style de trait de soulignement final de Google, car les ivars de soulignement de premier plan ont une gestion spéciale en valueForKey:, et je préfère éviter la magie des cas spéciaux.