Хорошо, вот сделка.
Когда вы определяете свойство как ...
@property (nonAtomic, retain) NSString myName;
... из-за значений по умолчанию команды свойства фактически все равно, что определять его как:
@property (nonAtomic, readwrite, retain, getter=getMyName,setter=setMyName) NSString myName;
Когда вы используете @synthesize myName;
за кулисами, компилятор генерирует метод получения, который выглядит примерно так:
-(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
}
}
Как вы можете видеть, любая строка из любого источника, с любым предшествующим счетом сохранения, автоматически освобожденным или нет, будет автоматически сохраняться методом при назначении, а когда назначается новое значение, он автоматически освобождается методом. Многократные назначения не будут составлять счет удержания. Пока вы используете сгенерированный сеттер, назначенный объект (в данном случае aString) всегда будет иметь счет сохранения, который будет поддерживать его в классе.
Вот почему вы можете сделать это ...
self.myName=[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"]
;
без необходимости делать это:
self.myName=[[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"] retain];
... и не нужно беспокоиться, если строковое значение внезапно исчезнет при сливе автозапуска.
Однако, если вы когда-нибудь позвоните ...
[self.myName release];
... где-нибудь за пределами dealloc
, тогда объект в собственности может быть обнулен, если вы не отследите его безжалостно. К тому же, если вы позвоните ..
[self.myName retain];
... где угодно, тогда объект в свойстве будет вытекать (возможно, даже после того, как собственный объект был освобожден.)
Вот почему я говорю, что никогда не следует сохранять или автоматически освобождать любой объект, назначенный или скопированный в свойстве. Это не только бессмысленно, но и контрпродуктивно. Из этого следует, что вы хотите вызывать release для свойства только тогда, когда вы закончили с объектом self, потому что эффективное отслеживание счетчика сохранений установщиком означает, что вы можете обнулить свойство, даже если оно вам все еще необходимо.
Авторелиз никогда не требуется для свойства, потому что свойство всегда сохраняется объектом self, и любой другой объект должен обрабатывать сохранение внутренне, если он использует свойство объекта self.
Как только вы понимаете, что происходит внутри сгенерированных средств доступа, правила становятся очевидными. Никогда не сохраняйте объект свойства явно. Никогда не выпускайте объект свойства, кроме как в dealloc. Никогда не высвобождайте объект автоматически.
Очевидным следствием этих правил всегда является использование ссылок self.propertyName внутри объекта self для обеспечения автоматического управления сохранением свойства.