2009-03-28 696 views
12

Supongamos que tengo una función como esta:Administración de memoria Objective-C: ¿mejores prácticas al devolver objetos?

- (NSSet *) someFunction { 
    //code... 
    return [[[NSSet alloc] initWithObjets:obj1, obj2, nil] autorelease]; 
} 

Cuando llamo a esta función, haga lo que necesito hacer retener/liberar el valor de retorno? Supongo que sí.

Sin embargo, ¿qué pasa si no lo hago autorelease, por lo algunaFuncion ahora se ve así:

- (NSSet *) someFunction { 
    //code... 
    return [[NSSet alloc] initWithObjets:obj1, obj2, nil]; 
} 

En este caso, estoy asumiendo que necesito para liberar pero no retener el valor de retorno.

Mi pregunta es, ¿cuál es la mejor práctica sugerida para este tipo de situaciones? ¿Se recomienda una u otra versión de alguna función? Gracias.

Respuesta

12

Debe pasar un tiempo leyendo Memory Management Programming Guide for Cocoa.

Lo corto es que si obtiene su referencia a través de un método que comienza con 'alloc' o 'new' o contiene 'copy', usted es el propietario de la referencia y no tiene que retenerla. Usted tiene previsto su lanzamiento, ya sea a través de una versión directa o mediante el uso de liberación automática.

Si obtiene una referencia de otra manera (a través de un método de clase o lo que sea), no posee una referencia, por lo que no tiene que liberarla. Si desea mantener una referencia, debe retenerla.

En general, es bastante simple y eficaz.

+0

es alloc, no init, lo que significa que usted es el propietario de la referencia Creo – cobbal

+0

Sí, está en lo correcto. Editando la respuesta original para reflejar eso (por el bien de la posteridad). –

+5

Veo tantas personas que se refieren a esa guía de programación. Es muy, muy aburrido y seco para leer. Es necesario que haya otra guía para ello –

2

Hmm ...

Normalmente, sigo este "camino".

+ (id)MyObj { 
    return [[[MyObj alloc] init] autorelease]; 
} 

Liberar el objeto antes de devolverlo, el objeto se desasignará antes de que llegue el objeto que llama. Esto producirá un error. Evite este error utilizando en su lugar un grupo de autorrelease. Originalmente presentado por Scott Stevenson de Theocacao. Es su forma preferida para Obj-C 1.0.

+0

normalmente uno nunca debería tener capital como la primera letra del nombre del método, a menos que sea una abreviatura común (por ejemplo, HTTPBody, URL). –

2

La única razón por la que debe hacer el código en el segundo ejemplo es si el nombre de su método comienza con nuevo, alloc, create, copy o algo así.

De lo contrario, usted es responsable de liberar (o autorrellenar) cualquier objeto que asigne. El primer ejemplo es la forma correcta de hacer la mayoría de las cosas.

La función de llamada debe conservar el valor si desea que persista más allá del alcance de las funciones, pero luego es responsable de liberarlo en algún momento posterior.