Tengo algunas preguntas sobre las propiedades sintetizadas en Objective-C. La lista completa sigue, pero la pregunta básica es la siguiente: ¿Cómo garantiza el compilador que los ivars para las propiedades sintetizadas se lanzan correctamente, aunque mi código puede incluir o no métodos de publicación en dealloc?¿Cómo se maneja la liberación para las propiedades de retención @synthesized?
Nota: decidí no publicar estas preguntas como individuales, ya que están tan estrechamente relacionados y porque hay un puñado de preguntas existentes que contacto sobre las cuestiones individuales sin realmente entrar en el meollo de la cuestión.
preguntas algo similar:
- Does property retain need a release?
- What's the difference between property and synthesize?
- Question on retain attribute with property and synthesize
Configuración: considerar una clase con una sola propiedad:
@interface Person : NSObject
{
NSString * name;
}
@property (nonatomic, retain) name;
@end
Pregunta # 1: El caso muy básico:
@implementation Person
@synthesize name;
@end
Con esta configuración, supongo que name
serán liberados automáticamente cada vez que se libera un objeto Person
. En mi opinión, el compilador simplemente inserta [name release]
en el método dealloc
como si yo mismo lo hubiera escrito. ¿Es eso correcto?
Pregunta # 2: Si decido a escribir mi propio método dealloc
para esta clase, y omito una llamada a [name release]
, habrá que escape?
@implementation Person
@synthesize name;
- (void)dealloc { [super dealloc]; }
@end
Pregunta # 3: Si decido a escribir mi propio método dealloc
para esta clase, y yo incluyo una llamada a [name release]
, hará que se traducen en una doble versión, ya que @synthesize
ya se ha ocupado de eso por mí?
@implementation Person
@synthesize name;
- (void)dealloc { [name release]; [super dealloc]; }
@end
Pregunta # 4: Si decido a escribir mi propio acceso a la propiedad de esta clase, pero No escribir mi propio método dealloc
, se name
ser filtrada?
@implementation Person
@dynamic name;
- (void)setName:(NSString *)newName
{
[newName retain];
[name release];
name = newName;
}
@end
Pregunta # 5: tengo la sensación (basado en la experiencia) que ninguno de los escenarios anteriores dará lugar a fugas o dobles comunicados, ya que el lenguaje ha sido diseñado para evitar ellos. Eso, por supuesto, plantea la pregunta de "¿cómo?". ¿Es el compilador simplemente lo suficientemente inteligente como para realizar un seguimiento de todos los casos posibles? ¿Y si tuviera que hacer lo siguiente (tenga en cuenta que este es un ejemplo absurdo, sólo significaba para ilustrar mi punto):
void Cleanup(id object) { [object release]; }
@implementation Person
@synthesize name;
- (void)dealloc { Cleanup(name); }
@end
Ojalá engañar al compilador en la adición de otra [name release]
al método dealloc
?
Gracias por la respuesta detallada. ¡Me alegro de haber preguntado! –
¡Muy bien explicado! –