2009-10-30 14 views
10

estoy leyendo hasta aproximadamente codificación y decodificación, me di cuenta de que a veces la gente se pierda la conservará fuera de la final, también me he dado cuenta que retienen a veces se utiliza en algunos varables pero no otros. ¿Puedo preguntar ...Uso de retener en initWithCoder?

(1) ¿Cuál es el propósito de esta retener y por qué es que a veces no se necesita?

(2) ¿El uso de la retención implica que tengo que coincidir con un lanzamiento, y en caso afirmativo, dónde?

- (id) initWithCoder: (NSCoder *) decoder { 
    name = [[decoder decodeObjectForKey: @"CardName"] retain]; 
    email = [[decoder decodeObjectForKey: @"CardEmail"] retain]; 
} 

o

- (id) initWithCoder: (NSCoder *) decoder { 
    name = [decoder decodeObjectForKey: @"CardName"]; 
    email = [decoder decodeObjectForKey: @"CardEmail"]; 
} 

Gary

+0

Lo más probable es que se ven ejemplos de código que no retienen explícitamente el objeto decodificado están utilizando métodos setter para reclamar la propiedad. – Chuck

Respuesta

12

Su primera snippit representa el comportamiento correcto. El método -decodeObjectForKey: no contiene la palabra init, copy o new, así que no hay promesa hecha sobre si el objeto devuelto se mantendrá en torno, y si es así por cuanto tiempo. Si su objeto necesita sus ivars para quedarse, debería -retain los objetos que obtiene del decodificador. Este -retain tendrá que ser equilibrado con un -release, que estará en el método de su objeto -dealloc (por lo que se crea el objeto con algunos Ivars iniciales que se retiene y libera su Ivars cuando es destruido). De esta manera:

- (void)dealloc { 
    [name release]; 
    [email release]; 
    [super dealloc]; 
} 

La retener/liberación no es necesaria la danza:

  • si está utilizando la recolección de basura

  • si su objeto no necesita reclamar la propiedad de su ivars. Eso no es a menudo el caso; por lo general, los delegados no son retenidos (pero normalmente tampoco se archivan), y las propiedades declaradas con el modificador assign tampoco lo son.

+0

Probablemente necesite otro viaje alrededor de la guía de gestión de memoria, ¿puedo preguntar si aloco una clase simple que contenga una sola variable de instancia NSString si la lanzo en mi dealloc o la liberaré cuando lance la instancia que contiene? – fuzzygoat

+0

sí, debe conservar la variable de instancia cuando se establece y liberarla cuando ya no sea necesaria. Tengo una publicación de blog con un conjunto de enlaces a artículos de gestión de memoria: http://iamleeg.blogspot.com/2008/12/cocoa-memory-management.html –

+0

Gracias, Graham, creo que ya llegué allí. , He vinculado tu publicación de blog para referencia futura. Ten un excelente fin de semana. – fuzzygoat

9

También es posible que las personas que usan las propiedades hayan sido engañadas. Su gente posible que usted ha visto haciendo:

- (id) initWithCoder: (NSCoder *) decoder { 
    self.name = [decoder decodeObjectForKey: @"CardName"]; 
    self.email = [decoder decodeObjectForKey: @"CardEmail"]; 
} 

que estaría bien si el nombre y el correo electrónico se definieron como propiedades 'retener'. Por supuesto, usted entra en la discusión acerca de si es legal/aconsejable usar accesadores de propiedad en los métodos initialise/dealloc - algunos dicen que sí, algunos dicen que no, Apple parece estar del lado de no, pero nunca han dado realmente un una buena razón por la que puedo ver.

Cuestiones relacionadas