2010-02-14 12 views
20

que tienden a liberar mis cosas en -dealloc, y ahora el iPhone OS 3.0 introdujo este método -viewDidUnload divertido, donde dicen:¿Qué debo hacer exactamente en viewDidUnload?

// liberar cualquier subvistas de la vista principal retenidos. // p.ej. self.myOutlet = nil;

So -viewDidUnload parece ser llamado cuando la vista del controlador de vista se inició desde la memoria. Y si tengo subvistas adjuntas a la vista principal del controlador de vista, tengo que liberar eso solo AQUÍ, pero no también en -dealloc.

Eso es confuso. Además, ¿qué ocurre si -dealloc hace que la vista se descargue (libere)? Entonces otra vez, llamará -viewDidUnload?

Me doy cuenta de la diferencia, que -viewDidUnload es solo para el caso donde la vista se mata, pero el controlador de vista permanece en la memoria. Y -dealloc es para el caso en el que todo se desperdicia.

Quizás alguien pueda aclarar la confusión.

+1

Pregunta similar: http://stackoverflow.com/questions/1158788/when-should-i-release-objects-in-voidviewdidunload-rather-than-in-dealloc –

+0

viewDidUnload está en desuso en iOS 6! – whyoz

Respuesta

37

La intención aquí es "equilibrar" la gestión de su subvista. Todo lo que cree en viewDidLoad debe ser lanzado en viewDidUnload. Esto hace que sea más fácil hacer un seguimiento de lo que se debe liberar donde. En la mayoría de los casos, su método dealloc es una imagen espejo de su método init, y su viewDidUnload será una imagen especular de su método viewDidLoad.

Como ha señalado, los métodos viewDid ... se deben usar cuando la vista se carga y descarga. Esto permite que un patrón de uso en el que el controlador de vista permanece cargado en la memoria, pero la vista en sí mismo puede ser cargado y descargado según sea necesario:

init 
viewDidLoad 
viewDidUnload 
viewDidLoad 
viewDidUnload 
... 
dealloc 

Por supuesto, no hace daño a liberar las cosas en su método como dealloc bien, siempre que los configure en nil cuando los suelta en viewDidUnload.

La siguiente cita de la sección Administración de la memoria de Apple UIViewController documentation, lo describe con más detalle:

... en el iPhone OS 3.0 y versiones posteriores, el método viewDidUnload puede haber un lugar más apropiado para la mayoría de las necesidades .

Cuando se produce una advertencia de poca memoria, la clase UIViewController purga sus vistas si sabe que puede volver a cargarlas o recrearlas más tarde. Si esto ocurre, también llama al método viewDidUnload para darle al código la oportunidad de renunciar a la propiedad de cualquier objeto asociado con su jerarquía de vistas, incluidos los objetos cargados con el archivo nib, los objetos creados en su método viewDidLoad y los objetos creados de forma perezosa en tiempo de ejecución y agregado a la jerarquía de vista. Normalmente, si su controlador de vista contiene puntos de venta (propiedades o variables sin formato que contienen la palabra clave IBOutlet), debe usar el método viewDidUnload para renunciar a la propiedad de esos puntos de venta o cualquier otro dato relacionado con la vista que ya no necesite.

+0

viewDidUnload no es un reflejo de viewDidLoad ya que el método Unload establece outlets en nil. –

+1

¿A qué método de descarga se refiere? Eché un vistazo a la documentación de UIViewController, pero no encontré un método con ese nombre. Cuando describí viewDidUnload como siendo (normalmente) una imagen reflejada de viewDidLoad, quise decir en términos de gestión de memoria; es decir: todo lo que se haya asignado, copiado o retenido en viewDidLoad se debe liberar en viewDidUnload. IBOutlets generalmente se configuran automágicamente cuando se carga el archivo nib, por lo que incluso si están configurados en nil antes de la llamada a viewDidUnload, eso no debería afectar nada desde el punto de vista de la memoria. –

+0

Para ser claro; Puedo ver cómo sería * posible * tener problemas si asignara un objeto en viewDidLoad que fuera inaccesible en viewDidUnload cuando todas las IBOutlets se hubieran establecido en nil. Sin embargo, esto sería un fuerte indicio de mal diseño, ya que un objeto siempre debe mantener un puntero a cualquier memoria que sea responsable de liberar. –

3

Como dices viewDidUnload se llamará si self.view = nil, esto generalmente ocurre si recibes una advertencia de memoria. En este método, debe liberar cualquier subvista de la vista principal que pueda crearse fácilmente con el método .xib o loadView.Debería liberar cualquier objeto de datos si los crea en viewDidload o loadView, etc., ya que estos métodos serán llamados de nuevo para presentar la vista al usuario, esos datos pueden recrearse fácilmente.

0

Cuando recibe una advertencia de memoria, generalmente el controlador de vista descargará su vista, pero no será tratable.
Todo lo que se puede volver a crear fácilmente debe descargarse, pero no el modelo de la vista.

Cuestiones relacionadas