Bien, este es el trato.
Cuando se define una propiedad como así ...
@property (nonAtomic, retain) NSString myName;
... debido a los valores predeterminados de la propiedad Command su realidad como lo define como:
@property (nonAtomic, readwrite, retain, getter=getMyName,setter=setMyName) NSString myName;
Cuando se utiliza @synthesize myName;
detrás de escena, el compilador genera un método getter que se ve así:
-(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
}
}
Como puede ver, cualquier cadena de cualquier fuente, de cualquier recuento de retención anterior, liberado automáticamente o no, se retendrá automáticamente por el método en la asignación y cuando se asigna un nuevo valor, se liberará automáticamente por el método. Las asignaciones múltiples no acumularán el conteo retenido. Siempre que use el setter generado, el objeto asignado (en este caso aString) siempre tendrá un conteo de retención que lo mantendrá con vida en la clase.
Es por esto que usted puede hacer esto ...
self.myName=[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"]
;
sin tener que hacer esto:
self.myName=[[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"] retain];
... y no tener que preocuparse de si el valor de la cadena de repente desaparecen cuando los desagües autoreleasepool.
Sin embargo, si alguna vez llama ...
[self.myName release];
... cualquier lugar fuera del dealloc
, entonces el objeto en la propiedad de mi ser nilled menos a seguirlo sin descanso. Por la misma razón, si llamas ...
[self.myName retain];
... en cualquier lugar, el objeto de la propiedad se escapará (posiblemente incluso después de que el objeto mismo se ha desasignado.)
Es por esto que digo que nunca para retener o AutoRelease cualquier objeto asignado o copiado en una propiedad. No solo es inútil sino contraproducente. De esto se deduce que solo desea ejecutar el lanzamiento en una propiedad cuando haya terminado con el objeto propio porque el seguimiento eficiente del recuento retenido por el colocador significa que puede anular la propiedad aunque aún pueda necesitarla.
Nunca se necesita autorización para una propiedad porque la propiedad siempre es retenida por el objeto y cualquier otro objeto debe gestionar la retención internamente si utiliza la propiedad del objeto propio.
Una vez que comprenda lo que sucede dentro de los descriptores de acceso generados, las reglas son obvias. Nunca retenga el objeto de una propiedad explícitamente. Nunca libere el objeto de una propiedad guardado en dealloc. Nunca desbloquees el objeto de una propiedad.
El corolario obvio de estas reglas es usar siempre las referencias de self.propertyName internamente en el objeto self para garantizar que la retención de la propiedad se administre automáticamente.
En su EDIT 1, retenga-cuente sabiamente, son lo mismo. Esos objetos son retenidos solo una vez. Hay un autodesbloqueo implícito en TODAS las funciones de conveniencia. Si no ves la palabra alloc en el enunciado init, la variable se libera automáticamente. Si usa alloc, debería usar autorelease –