2010-02-17 7 views
7

Soy nuevo en el objetivo c y trato de entender cómo y cuándo se llama la liberación automática. Entiendo el caso de uso simple:¿El retorno de autorrelease es un error en el objetivo c?

- (void) foo { 
    Bar *b = [[[Bar alloc] init] autorelease]; 
    [self doSomething:b]; 
    } 

¿Qué pasa con este caso siguiente - es esto un error, porque el objeto se dará a conocer inmediatamente después de salir del alcance de makeBar?

-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

¿Qué pasa si la persona que llama realiza una retención?

Bar *b = [[self makeBar] retain]; 

Gracias, -Eric

+1

Este contenido de esta pregunta y las dos respuestas siguientes deben estar en la lista de lectura obligatoria para los nuevos en ObjC – ckhan

Respuesta

7

En el segundo ejemplo, el objeto anónimo usted está volviendo no serán liberados tan pronto como la ejecución sale del alcance de makeBar pero en la siguiente iteración de la carrera lazo. Esto le dará la oportunidad de retain en el método que ha llamado makeBar

Así que su último ejemplo es aceptable ya que la cuenta de retención no caerá por debajo de 0.

¿Está teniendo problemas con ella?

+1

Para ser más específicos, se lanzará cuando el grupo de liberación automática al que se agregó se haya drenado/liberado. Esto es típicamente al final de un ciclo de ejecución, pero no siempre. – dreamlax

+0

Sin problemas, recién he estado escaneando mi código en busca de posibles problemas de memoria y vi ese patrón a partir del código de muestra que había copiado y no estaba seguro de si era un error o no. – esilver

5
-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

El segundo caso es el preferido manera de devolver un objeto Objetivo-C. Excepto +alloc, -copy... y -create..., el método debe retener no la propiedad del objeto de volver, es decir, el (cambio de) retener recuento debe ser 0.

Sin embargo, [[Bar alloc] init] hace que el objeto de tener retainCount de 1, para uno debería liberarlo antes de regresar. Pero -release desasignará inmediatamente el objeto, haciendo que el método sea inútil. Es por eso que se usa -autorelease - es un retrasado-release, es decir, el objeto se lanzará eventualmente, pero no ahora, por lo que otras partes del código aún pueden interactuar con él, sin embargo, el conteo retenido aún se puede equilibrar a 0.


Bar *b = [[self makeBar] retain]; 

debe no retenerlo a menos que usted quiere ser dueño de un largo plazo del objeto b.

Cuestiones relacionadas