2009-02-24 11 views
6

Me preguntaba cómo funciona el autorelease en el iPhone. Pensé que una vez que envíe una liberación automática a un objeto se garantiza que se conserve hasta que se haya enviado el autorelease hasta el final del bloque. ¿Es eso correcto?Autorelease scope

estaba inicializando una vista desde una ONI en el applicationDidFinishLaunching, como a continuación:

(void)applicationDidFinishLaunching:(UIApplication *)application { 

    loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; 

    [window addSubview: [loginViewController view]]; 
    [window makeKeyAndVisible]; 
} 

y la vista no se presentó en absoluto, todo lo que había en la pantalla fue el UIWindow

Ahora, una vez que eliminado el autorelease desde el final de la inicialización del controlador, todo transcurrió sin problemas a partir de ese momento.

¿De qué se trata?

Cheers, K.

Respuesta

13

Cuando llama al autorelease, otorga la propiedad del objeto al grupo de autorrelease actual. El ciclo de ejecución crea un nuevo conjunto de autorrelease antes de que distribuya un evento (como applicationDidFinishLaunching:) y destruye ese grupo cuando finaliza el evento.

Cuando cede la propiedad de su LoginViewController al grupo de liberación automática, se libera justo después de la devolución de applicationDidFinishLaunching:. Cuando el controlador de vista se desasigna, elimina su vista de la supervista (su ventana en este caso).

Su delegado aplicación debe mantener la propiedad de la LoginViewController y release que en el método del delegado de la aplicación dealloc (o cuando haya terminado con su nombre de usuario y que ha pasado a otra vista).

0

El autoreleasepool se limpia al final de la runloop. Esto significa que siempre que invoque métodos y haga cosas, aún estará allí.

No veo el error en su código, pero la ventana se conserva correctamente en su ejemplo.

0

Dado que está agregando su LoginViewController al grupo de liberación automática, se lanzará al final del ciclo de ejecución. Cuando eso sucede, también libera su 'vista y elimina su visualización.

+0

La ventana debe conservar la vista. (Aunque no tengo acceso a la documentación) –

+1

Pero cuando el controlador de vista se desasigna, elimina la vista que administra de su supervista. –

+0

Precisamente lo que dijo Don. –

4

Para ampliar la respuesta de Don, puede ser un tanto confuso decir "cede el objeto al grupo de autorrelease actual". Esto podría malinterpretarse en el sentido de que se garantiza que el objeto se destruirá cuando se vacíe el conjunto de autorrelease. Esto no es correcto (aunque sucederá en este caso). El envío de -autorelease solicita que el grupo de liberación automática envíe un mensaje -release cuando se vacía. Si ese mensaje -release hace retainCount = 0, entonces el objeto será destruido.

Por lo tanto, para hacer lo que Don recomienda, debe crear un ivar para realizar un seguimiento de este controlador de vista. Su explicación de por qué la vista se desvanece es exactamente correcta; pero no desea simplemente filtrar el controlador de vista. Desea retenerlo y liberarlo cuando haya terminado con él.

@interface ... { 
    LoginViewController *_loginViewController; 
} 

@property (readwrite, retain) LoginViewController *loginViewController; 

@implementation ... 
@synthesize loginViewController = _loginViewController; 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    self.loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; 

    [window addSubview: [loginViewController view]]; 
    [window makeKeyAndVisible]; 
} 

- (void)dealloc { 
    [_loginViewController release]; _loginViewController = nil; 
    [super dealloc]; 
}