que create iphone memory-management uiviewcontroller

iphone - create - viewcontroller ionic



didReceiveMemoryWarning, viewDidUnload y dealloc (4)

didReceiveMemoryWarning

...

Acción: libere todo lo que no necesite, es probable que esté deshaciendo lo que pudo haber configurado en viewDidLoad.

Esto está mal. Todo lo que viewDidLoad crear en viewDidLoad debe publicarse (y establecerse en nil ) en viewDidUnload . Como mencionas a continuación, didReceiveMemoryWarning también se llama cuando la vista está visible. En didReceiveMemoryWarning , debe liberar elementos como cachés u otros controladores de vista que está guardando para que se puedan recrear perezosamente la próxima vez que se requieran (es decir, implementando su getter manualmente).

viewDidUnload

...

Acción: en general, cualquier IBOutlets que libere en dealloc, también debe ser liberado (y las referencias deben establecerse en cero) en este método. Tenga en cuenta que si las propiedades se configuran para retenerlas, entonces establecerlas en nil también las liberará.

Correcto. En general, todo lo que crea en viewDidLoad y todos los IBOutlets que se declaran como retain deben publicarse y establecerse en nil aquí.

Dealloc

...

Acción: libere todos los objetos que han sido retenidos por la clase, incluidos, entre otros, todas las propiedades con retener o copiar.

Correcto. Vale la pena señalar que esto incluye todos los objetos que maneja en viewDidUnload porque este último no se llama implícitamente en el proceso de dealloc (AFAIK, no del todo seguro). Es por eso que es esencial establecer todos los objetos de lanzamiento en nil en viewDidUnload porque de lo contrario, se arriesga a soltar algo dos veces (primero en viewDidUnload y luego nuevamente en dealloc ; si establece el puntero en nil , la llamada de lanzamiento en dealloc no tendrá efecto).

Controladores de vista emergente y memoria

Pregunta 2: ¿Al abrir una vista, se elimina de la memoria?

No necesariamente. Ese es un detalle de implementación que no debería preocuparle. Cualquiera que sea la práctica actual, Apple podría cambiarla en la próxima versión.

He revisado muchas publicaciones, mis libros y el Desarrollador de Apple y he recogido la mayor parte de la comprensión que necesito sobre el uso de estos. Estaría muy agradecido si alguna persona amable pudiera confirmar que lo he entendido bien (o corregirme) y también responder las dos preguntas.

Muchas gracias,

Chris

Orden de los mensajes En general, los mensajes aparecerán en el siguiente orden:

  • didReceiveMemoryWarning

  • viewDidUnload (que puede ser causado por 1), obviamente solo se aplica a las clases de controlador de vista.

  • Dealloc

didReceiveMemoryWarning

Se llama cuando el sistema tiene poca memoria.

De forma predeterminada, los controladores de vista están registrados para las notificaciones de advertencia de memoria y, dentro del método de plantilla, la llamada a [super didReceiveMemoryWarning] libera la vista si no tiene una vista de supervisión, que es una forma de verificar si la vista es visible o no. Libera la vista estableciendo su propiedad en nil.

Acción: libere todo lo que no necesite, es probable que deshaga lo que haya configurado en viewDidLoad. No libere elementos de la interfaz de usuario, ya que estos deberían ser publicados por viewDidUnload.

Pregunta 1: parece que esto se llamará incluso si la vista es visible, por lo que es difícil ver lo que se puede liberar de forma segura. Sería muy útil entender esto y algunos ejemplos de lo que podría ser publicado.

viewDidUnload

Se llama cuando una propiedad de vista del controlador de vista no visible se establece en nulo, ya sea de forma manual o más comúnmente a través de didReceiveMemoryWarning.

El método viewDidUnload está allí para que pueda: - limpiar cualquier otra cosa que desee, para ahorrar memoria extra o - si ha conservado algunos IBOutlets, para ayudar a liberar memoria que de otro modo no se liberaría al descargar la vista .

Acción: en general, cualquier IBOutlets que libere en dealloc, también debe ser liberado (y las referencias deben establecerse en cero) en este método. Tenga en cuenta que si las propiedades se configuran para retenerlas, entonces establecerlas en nil también las liberará.

Dealloc

Se invoca cuando el objeto del controlador de vista se desasigna, que será cuando el recuento de retención caiga a cero.

Acción: libere todos los objetos que han sido retenidos por la clase, incluidos, entre otros, todas las propiedades con retener o copiar.

Controladores de vista emergente y memoria

Pregunta 2: ¿Al abrir una vista, se elimina de la memoria?


A partir de iOS 6, cómo podemos comprobar si la vista se ha cargado de nuevo. Dado que "viewDidUnload" está en desuso. ¿Está seguro de que "loadView" y "viewDidload" llamarán si la vista se está eliminando después de la advertencia "didReceiveMemoryWarning"?


Algunas correcciones y sugerencias:

  • didReceiveMemoryWarning prácticas

Como ha dicho, la implementación predeterminada del controlador didReceiveMemoryWarning publica su vista si es "seguro hacerlo". Si bien no está claro en los documentos de Apple lo que significa "seguro hacerlo", generalmente se reconoce que no tiene supervisión (por lo tanto, no hay forma de que la vista esté actualmente visible), y su método loadView puede reconstruir la vista completa sin problemas. .

La mejor práctica cuando reemplaza didReceiveMemoryWarning es no intentar liberar ningún objeto de vista. Solo libere sus datos personalizados, si ya no es necesario. Con respecto a las vistas, simplemente deje que la implementación de la superclase se ocupe de ellas.

A veces, sin embargo, la necesidad de los datos puede depender del estado de su vista. En la mayoría de los casos, esos datos personalizados se configuran en el método viewDidLoad . En estos casos, ''seguro para liberar datos personalizados'' significa que sabe que loadView y viewDidLoad se invocarán antes de que el controlador de vista vuelva a utilizar los datos personalizados.

Por lo tanto, en su didReceiveMemoryWarning , llame primero a la implementación de la superclase, y si se descarga su vista, entonces libere los datos personalizados porque sabe que se invocarán de nuevo loadView y viewDidLoad . Por ejemplo,

- (void)didReceiveMemoryWarning { /* This is the view controller''s method */ [super didReceiveMemoryWarning]; if (![self isViewLoaded]) { /* release your custom data which will be rebuilt in loadView or viewDidLoad */ } }

Tenga cuidado de no usar self.view == nil , porque self.view asume que la vista es necesaria para alguien e inmediatamente la cargará de nuevo.

  • método viewDidUnload

Se llama a viewDidUnload cuando el controlador de vista descargó la vista debido a una advertencia de memoria . Por ejemplo, si elimina la vista de la vista de supervisión y configura la propiedad de view del controlador en nil , no se invocará el método viewDidUnload . Un punto sutil es que incluso si la vista de un controlador de vista ya se publicó y se establece en nulo en el momento en que el controlador recibe didReceiveMemoryWarning , por lo que en realidad no hay una vista para descargar para el controlador, se invocará viewDidUnload si llama a la implementación de la superclase de didReceiveMemoryWarning .

Por eso no es una buena práctica establecer manualmente la propiedad view de un controlador de vista en nil. Si lo hace, también puede enviar un mensaje viewDidUnload . Supongo que su comprensión de viewDidUnload es más deseable, pero aparentemente no es el comportamiento actual.

  • Controladores de vista emergente

Si quiere decir ''eliminar de la vista de supervisión'' por ''hacer estallar'', disminuye el recuento de retención de la vista, pero no necesariamente la desasigna.

Si quiere decir que está saliendo de un UINavigationController, en realidad disminuye el conteo de retención del propio controlador de vista. Si el controlador de vista no es retenido por otro objeto, será desasignado, deseablemente con su vista. Como expliqué, viewDidUnload no se invocará esta vez.

  • Otros...

Técnicamente, la cuenta de retención no puede bajar a cero. Es más probable que el objeto se desasigne sin establecer el recuento en cero de antemano.

Solo para asegurarse, el controlador de vista en sí no suele ser desasignado por comportamientos predeterminados debido a la advertencia de memoria.