Liberación del controlador de vista principal (iOS)
Frecuentes
Visto 348 veces
0
He buscado esto en el sitio de Apple y parece que solo puedo encontrar documentación usando Storyboards o Navigation Controllers, ninguno de los cuales estoy usando. Es una pregunta increíblemente sencilla sobre la gestión de la memoria.
Creé una aplicación completamente en blanco. En la función didFinishLaunchingWithOptions de mi AppDelegate, estoy creando una instancia de un controlador de vista que he creado. Mi diseño (que en sí mismo podría ser un problema) es tener una relación 1: 1 entre los controladores de vista y las vistas.
Entonces, el menú principal de mi aplicación, que es una plataforma de lanzamiento para todo, está en MenuViewController.h/m.
En .h:
MenuViewController *m;
En m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
m = (MenuViewController *)[[MenuViewController alloc] init];
m.window = self.window;
[m doStuff]; // handful of functions, not actually called this
//[m release]; // doesn't make sense to me
return YES;
}
Aquí es donde estoy confundido. Quiero que esto exista básicamente durante todo el ciclo de vida de la aplicación. Pero también tengo la impresión de que debería (en el ámbito de la función actual) liberar todo lo que asigne. Si lo necesita más allá de eso, debe conservarlo en otro lugar primero. ¿No es esto cierto?
Mi pregunta fundamental es... ¿dónde debo lanzar este controlador de vista? ¿Hay algo más que haya dicho que parezca fuera de lugar?
2 Respuestas
2
La inicialización es incorrecta. No asigna una ventana al controlador, asigna un controlador a la ventana:
// window creation code here
...
m = [[MenuViewController alloc] init];
[window setRootViewController:m]; // window does retain for m
[m release]; // so we release it here
[self.window makeKeyAndVisible];
return YES
}
contestado el 22 de mayo de 12 a las 21:05
RootViewController para mí implica uno. ¿Es un diseño incorrecto o deficiente tener un controlador de vista para cada "pantalla" en mi aplicación? Actualmente tengo uno para el Menú principal, la pantalla de carga, una pantalla para crear usuarios, una pantalla para administrar otros datos, etc. - JamesB41
Así es exactamente como se supone que debes hacerlo. Por supuesto, en algunos casos puede ser razonable usar una subclase de controlador de vista más de una vez, pero para pantallas que son muy diferentes en naturaleza y función, generalmente tiene una subclase de controlador de vista separada. - BateristaB
@ JamesB41 es por eso que la mayoría de las aplicaciones tienen controladores de barra de pestañas o controladores de navegación que permiten presentar algunos controladores de vista o tener una navegación detallada. - Eimantas
Ok, pero ¿puede ser solo un RootViewController? Si estoy mostrando otra parte de pantalla completa de mi aplicación, ¿configuro el nuevo controlador como RootViewController? ¿Qué hace eso, además de traerlo al frente (supongo?)? - JamesB41
Sí, solo puede haber un controlador de vista raíz. Y si debe cambiarlo para mostrar otra pantalla, está haciendo algo mal. - Eimantas
0
Tienes razón. En general, debe publicar cualquier cosa que cree en un alcance. Pero en este caso, desea la propiedad del controlador de vista. En este caso, debe soltar el objeto en el dealloc
método del delegado de su aplicación:
- (void)dealloc {
[m release];
[super dealloc];
}
Alternativamente, podría definir un @property
para su controlador de vista con bandera de retención y luego haga esto:
MenuViewController *viewController = [[MenuViewController alloc] init];
self.m = viewController;
[viewController release];
Por cierto, no es necesario enviar a MenuViewController en ningún caso.
EDITAR: Me perdí por completo que no agregue su controlador de vista a su ventana. Buen punto @Eimantas.
contestado el 22 de mayo de 12 a las 21:05
Solo necesitaba emitirlo porque después llamé a un método desde AppDelegate y estaba lanzando una advertencia. - JamesB41
¿Importó el encabezado de su controlador de vista en el delegado de su aplicación? Si su variable (m) es del tipo MenuViewController (que es según su publicación) y el valor que le está pasando es del mismo tipo, entonces no necesita emitir. Esa advertencia tenía que tener otra razón. - BateristaB
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas objective-c ios memory-management or haz tu propia pregunta.
¿Por qué no usaste el conteo automático de referencias? (Tal vez podrías lanzarlo en
applicationWillTerminate:application
del AppDelegate) - ChrisLo soltará antes de pasar a la siguiente vista. También puede hacerlo en el método viewDidUnload o dealloc - anuragbh