Bon, voici l'affaire.
Lorsque vous définissez une propriété comme si ...
@property (nonAtomic, retain) NSString myName;
... en raison des défauts de la propriété Command est en fait comme le définir comme:
@property (nonAtomic, readwrite, retain, getter=getMyName,setter=setMyName) NSString myName;
Lorsque vous utilisez @synthesize myName;
Dans les coulisses, le compilateur génère une méthode getter qui ressemble à ceci:
-(void) setMyName:(NSString *) aString{
if (!(myString==aString) { //test if a string is the same **object** as the current myString
if (aString != nil) { // if nil we don't want to send a retain
[aString retain]; // increment the retain count by one
}
[myString release]; //decrement the retain count of the currently assigned string by one.
myString=nil; //set the pointer to nil to ensure we don't point to the old string object
myString=aString; //assign the newly retained object to the myString symbol
}
}
Comme vous pouvez le voir, toute chaîne de n'importe quelle source, de tout compte de retenue préalable, auto-libérée ou non, sera automatiquement retenue par la méthode lors de l'assignation et lorsqu'une nouvelle valeur est assignée, elle sera automatiquement libérée par la méthode. Les affectations multiples n'empilent pas le nombre de retenues. Tant que vous utilisez le setter généré, l'objet affecté (dans ce cas aString) aura toujours un nombre de retain qui le maintiendra en vie dans la classe.
C'est pourquoi vous pouvez le faire ...
self.myName=[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"]
;
sans avoir à faire:
self.myName=[[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"] retain];
... et ne pas avoir à vous inquiéter si la valeur de chaîne disparaît soudainement lorsque les drains autoreleasepool.
Toutefois, si vous appelez jamais ...
[self.myName release];
... partout en dehors de la dealloc
, l'objet dans la propriété de mon être nilled à moins que vous suivre implacablement. De même, si vous appelez ..
[self.myName retain];
... partout, l'objet dans la propriété fuira (peut-être même après que l'objet auto a été désallouée.)
C'est pourquoi je ne dis jamais de conserver ou autorelease tout objet ou affecté copié dans une propriété. Ce n'est pas seulement inutile mais contre-productif. Il s'ensuit que vous ne voulez appeler la libération d'une propriété que lorsque vous en avez terminé avec l'objet self car le suivi efficace du nombre de retenues par le setter signifie que vous pouvez ignorer la propriété même si vous en avez toujours besoin.
La libération automatique n'est jamais nécessaire pour une propriété car la propriété est toujours conservée par l'objet self et tout autre objet doit gérer la rétention interne s'il utilise la propriété de l'objet self. Une fois que vous avez compris ce qui se passe à l'intérieur des accesseurs générés, les règles sont évidentes. Ne conservez jamais l'objet d'une propriété explicitement. Ne jamais libérer l'objet d'une propriété, sauf en dealloc. Ne libérez jamais automatiquement l'objet d'une propriété.
Le corollaire évident de ces règles est toujours d'utiliser les références self.propertyName en interne dans l'objet self pour garantir que la rétention des propriétés est automatiquement gérée.
Sur votre EDIT 1, retenez-compte, ils sont identiques. Ces objets sont tous deux conservés une seule fois. Il y a une libération automatique implicite dans TOUTES les fonctions de commodité. Si vous ne voyez pas le mot alloc dans l'instruction init, la variable est autoeleased. Si vous utilisez alloc, vous devez utiliser autorelease –