Respuestas:
Además de lo que ya se ha indicado, quería elaborar más sobre la lógica detrás -viewDidUnload
.
Una de las razones más importantes para implementarlo es que las UIViewController
subclases comúnmente también contienen referencias de propiedad a varias subvistas en la jerarquía de vistas. Estas propiedades podrían haberse establecido IBOutlets
al cargar desde una plumilla, o mediante programación dentro -loadView
, por ejemplo.
La propiedad adicional de las subvistas UIViewController
significa que incluso cuando su vista se elimina de la jerarquía de vistas y se libera para ahorrar memoria, a través de la cual las subvistas también son liberadas por la vista, en realidad no se desasignarán porque la UIViewController
propia vista todavía contiene sus propios pendientes. conservando referencias a esos objetos también. Liberar la UIViewController
propiedad adicional de estos objetos asegura que también se desasignarán para liberar memoria.
Los objetos que libera aquí generalmente se recrean y configuran nuevamente cuando la UIViewController
vista es re-loaded
, ya sea desde un Nib o mediante una implementación de -loadView
.
También tenga en cuenta que la UIViewController
view
propiedad es nil
en el momento en que se llama a este método.
Como dice la documentación :
Se llama durante condiciones de poca memoria cuando el controlador de vista necesita liberar su vista y cualquier objeto asociado con esa vista para liberar memoria.
En la misma situación dealloc
está no llama. Este método solo está disponible en OS3 y versiones posteriores. ¡Tratar con la misma situación en iPhone OS 2.x fue un verdadero dolor!
Actualización de julio de 2015 : debe tenerse en cuenta que viewDidUnload
quedó obsoleto en iOS 6 porque "Las vistas ya no se purgan en condiciones de poca memoria, por lo que este método nunca se llama". Entonces, el consejo moderno es no preocuparse por él y usarlo dealloc
.
Esto se debe a que normalmente configurará el @property
como "(nonatomic, retain)"
y, como tal, el establecedor que se crea para usted libera el objeto actual y luego retiene el argumento, es decir
self.property = nil;
... hace algo como:
[property release];
property = [nil retain];
Por lo tanto, está matando dos pájaros de un tiro: administración de memoria (liberando el objeto existente) y asignando el puntero a nil (ya que enviar cualquier mensaje a un puntero nil devolverá nil).
Espero que ayude.
Recuerde que viewDidUnload
es un método en el controlador de vista, no en la vista. La de vista dealloc
método será llamado cuando la vista se descargue, pero la del controlador de vista dealloc
método no puede ser llamado hasta más tarde.
Si recibe una advertencia de memoria baja y su vista no se muestra, lo que sucederá, por ejemplo, cada vez que use un UIImagePickerController para permitir que el usuario tome una foto, su vista se descargará y deberá volver a cargarla después de eso.
Conclusión:
Los controladores de vista tienen una propiedad de vista. Normalmente, una plumilla o un fragmento de código agrega otras vistas a esta vista. Esto sucede a menudo dentro de un método -viewDidLoad, como este:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
Además, un archivo nib puede crear un botón y agregarlo a la vista del controlador de vista.
En iPhone OS 2.2, cuando se invocaba -didReceiveMemoryWarning desde el sistema, tenía que liberar algo para liberar memoria. Podría liberar la vista del controlador de vista completo si eso tuviera sentido. O simplemente contenidos que consumen mucha memoria.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
Ahora, en el nuevo OS 3.0, hay un método -viewDidUnload, que se invocará desde el sistema cuando la vista se haya descargado debido a poca memoria (corríjame: ¿cuándo exactamente se llama a esto?)
-viewDidUnload se usa para liberar todos los objetos que eran propiedad tanto del controlador de vista como de la vista. La razón: si un controlador de vista contiene referencias a elementos secundarios de la vista, es decir, un botón, las vistas secundarias a las que se hace referencia no se liberarán, porque su recuento de retención es> = 1. Una vez que se publican en -viewDidUnload, pueden liberarse de memoria.
Apple desaprobó viewWillUnload, ahora debe usar didReceiveMemoryWarning o dealloc para liberar sus objetcs.
En iOS 6, los métodos viewWillUnload y viewDidUnload de UIViewController ahora están en desuso. Si estaba utilizando estos métodos para liberar datos, utilice el método didReceiveMemoryWarning en su lugar. También puede utilizar este método para liberar referencias a la vista del controlador de vista si no se está utilizando. Debería probar que la vista no está en una ventana antes de hacer esto.
Si el controlador de vista se extrae de la pila de controladores de navegación y no se conserva en ningún otro lugar, se desasignará y se llamará a dealloc en lugar de viewDidUnload. Debería liberar las vistas creadas en loadView en dealloc, pero no es necesario establecer las variables en nil, porque poco después de llamar a dealloc, las variables dejarán de existir.