82 votes

Quelle est la différence entre ivars et propriétés en Objective-C

Je suis sûr que cette question n’a pas été formulée de cette façon avant, mais si elle a s’il vous plaît accepter mes excuses. Fondamentalement, je voudrais une explication claire définitive au sujet de la différence sémantique entre ces 3 façons d’utiliser ivars et propriétés en objective-c, en accordant une attention particulière à la première mise en œuvre :

1.

2.

3.

57voto

willc2 Points 8732

Numéro 1 diffère des deux autres par l'avant de déclarer la MyOtherObject classe de réduire la quantité de code vu par le compilateur et l'éditeur de liens et aussi potentiellement d'éviter les références circulaires. Si vous le faites de cette façon, n'oubliez pas de mettre le #importer dans le .m de fichier.

En déclarant un @biens, et la correspondance @synthétiser dans le .m) de fichiers, vous générez automatiquement des méthodes d'accès à la mémoire sémantique manipulés comment vous spécifiez. La règle de base pour la plupart des objets est de Retenir, mais NSStrings, par exemple, doit utiliser la Copie. Alors que les Singletons et les Délégués doivent généralement utiliser les Affecter. La main écrit des accesseurs est fastidieux et source d'erreurs, donc cela permet d'économiser beaucoup de temps de frappe et muets de bugs.

Aussi, la déclaration d'une synthétisés de la propriété vous permet d'appeler une méthode d'accesseur en utilisant la notation point comme ceci:

self.otherObj = someOtherNewObject; // set it  
MyOtherObject *thingee = self.otherObj; // get it 

Au lieu de la normale, de transmission de message de la manière:

[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it 

Derrière les scènes que vous avez vraiment appeler une méthode qui ressemble à ceci:

- (void) setOtherObj:(MyOtherObject *)anOtherObject {

    if (otherObject == anOtherObject) {
    return;  
    }

    MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
    otherObject = [anOtherObject retain]; // put the new value in  
    [oldOtherObject release]; // let go of the old object
} // set it

...ou cette

- (MyOtherObject *) otherObject {  
    return otherObject;
} // get it

Total de la douleur dans le cul, à droite. Maintenant le faire pour tous les ivar dans la classe. Si vous ne le faites pas exactement droite, vous obtenez une fuite de mémoire. Préférable de laisser le compilateur faire le travail.

Je vois que le Numéro 1 n'a pas d'ivar. En supposant que ce n'est pas une faute de frappe, c'est bien parce que les @property / @synthétiser les directives de déclarer une ivar pour vous aussi, derrière les coulisses. Je crois que c'est nouveau pour Mac OS X Snow Leopard et de l'iOS4.

Numéro 3 n'a pas ces accesseurs généré de sorte que vous avez à les écrire vous-même. Si vous voulez que vos méthodes accesseur pour avoir des effets secondaires, vous faites votre gestion de mémoire standard de la danse, comme indiqué ci-dessus, puis faire quelque côté que ce travail vous avez besoin, à l'intérieur de la méthode d'accesseur. Si vous synthétiser une propriété ainsi que l'écriture de vos propres, alors votre version a la priorité.

Je n'ai tout couvrir?

17voto

David H Points 23654

De retour dans les vieux jours où vous avez eu ivars, et si vous voulais quelque autre classe ou de les lire alors que vous aviez à définir un getter (c'est à dire, -(NSString *)foo) et un setter (c'est à dire, -(void)setFoo:(NSString *)aFoo;).

Quelles propriétés vous donner est le setter et getter gratuitement (ou presque!) avec un ivar. Ainsi, lorsque vous définissez une propriété maintenant, vous pouvez définir l'atomicité (voulez-vous permettre à de multiples actions de réglage à partir de plusieurs threads, par exemple), et d'affecter/conserver/sémantique de copie (qui est, si le setter de la copie de la nouvelle valeur ou simplement enregistrer la valeur actuelle important si une autre classe est d'essayer de mettre votre propriété de chaîne avec une mutable chaîne qui peut se changer plus tard).

C'est ce qu' @synthesize . De nombreuses personnes quittent l'ivar nom de le même, mais vous pouvez le changer quand vous écrivez votre synthétiser de l'énoncé (c'est à dire, @synthesize foo=_foo; moyen de faire un ivar nommé _foo pour les biens foo, donc si vous voulez lire ou d'écrire cette propriété et que vous n'utilisez pas d' self.foo,, vous devrez utiliser l' _foo = ... - il vous aide à reprendre des références directes à la ivar si vous voulais seulement passer par le setter et getter).

Comme de Xcode 4.6, vous n'avez pas besoin d'utiliser l' @synthesize déclaration - le compilateur fera automatiquement et par défaut, ajoute le ivar nom _.

0voto

Claptrap Points 21299

Lorsque vous déclarez une propriété que vous utilisez pour obtenir une valeur par défaut setter et getter pour un ivar. Votre (1) option semble pas valide.

(2) semble ok, vous êtes la création d'un setter et getter pour 'otherObj" bien que normalement j'ai l'habitude d'utiliser un nom différent pour le ivar pour faciliter la distinction entre les deux par exemple MyOtherObject* _otherObj et, plus tard, @synchroniser otherObj=_otherObj; Dans le dealloc méthode, vous pouvez relâcher le _otherObj ou de définir soi-même.otherObj = nil;

(3) ici, il n'y a pas de propriété, de sorte lorsque vous affectez à otherObj vous devez explicitement faire conserver et dans le dealloc méthode de libération de la variable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X