9

Es un patrón común en mi código para asignar un objeto, deja que haga un poco de materia con un manejador de terminación y lo liberan en el controlador:¿Cómo puedo liberar un objeto con un controlador de finalización de bloque en ARC?

LongOperation *foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [foo autorelease]; 
}]; 

Esto funciona bastante bien, pero cuando intento de convertir el código a ARC, Xcode se queja con razón de que no puede simplemente dejar caer el autorelease del bloque, ya que eso haría que el objeto foo fuera desasignado después de abandonar el alcance.

Entonces, ¿cuál es una buena manera de escribir este tipo de patrón en ARC? Podría introducir una variable de instancia para foo:

[self setFoo:[[LongOperation alloc] init]]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [self setFoo:nil]; 
}]; 

... pero el código no sería re-entrante más.

Respuesta

4

En la mayoría de los casos, debería funcionar (es decir, si algo hace referencia a self dentro de foo, foo durará lo suficiente como para satisfacer ese código antes de desaparecer). Si hay problemas con referencias débiles y de tal manera que foo parece que debería irse, pero debe no hasta después de que el controlador funciona, se puede hacer algo como:

__block LongOperation* foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // do some things 
    foo = nil; 
}]; 

Nota esto es un poco lo contrario de este patrón que hace que el objeto/no/sea capturado bajo las reglas de memoria administrada.

+0

Esto no responde a la pregunta es qué hacer cuando el contexto que contiene foo se ha ido. Con esta solución, el marco de pila que llama a [foo runWithCompletion:] debe bloquearse hasta que la ejecución se complete o se arriesgue a un apilamiento de pila. –

Cuestiones relacionadas