2009-02-24 14 views
12

Estoy en la parte de mi proceso de desarrollo para rastrear fallas de memoria y bloqueo. Como estrategia, ¿pones mensajes NSLog o notificaciones de algunos en didReceiveMemoryWarning:? La documentación para este método es bastante escasa. ¿Es correcto decir que antes de que ocurra un bloqueo, el UIViewController activará ese método? ¿Es ese un punto de partida antes incluso de seguir adelante con los instrumentos?iOS: utilidad de didReceiveMemoryWarning:

Respuesta

28

OK, varias cosas a tener en cuenta:

  • didReceiveMemoryWarning será llamado ante un accidente fuera de la memoria. No otros choques Si maneja la advertencia correctamente y libera la memoria, puede evitar la condición de falta de memoria y no fallar.
  • Puede activar manualmente una advertencia de memoria en el simulador en el menú Hardware. Recomiendo encarecidamente hacer esto para probar su manejo de didReceiveMemoryWarning.
  • Los instrumentos lo ayudan a depurar las fugas (aunque no a todas); en realidad no es tan útil para los bloqueos.
  • No, yo personalmente no utilizo NSLog - Solo interrumpo las advertencias de memoria cuando estoy depurando.
+0

Hola Airsource, ¿podría preguntar para qué sirve el 'Simulador -> Hardware -> Simular memoria de advertencia'? Cada vez que hago clic en él, solo aparece el mensaje "Recibí una advertencia de memoria simulada". en la consola ¿Cómo lo uso para 'eliminar problemas'? Gracias. – lionfly

+0

@lionfly: en respuesta a una advertencia de memoria, debe liberar la mayor cantidad de memoria posible. Simular una advertencia de memoria le permite verificar (y depurar) la ruta del código. –

3

El propósito de didReceiveMemoryWarning es darle la oportunidad de liberar vistas de memoria o pop para evitar un bloqueo. No lo recibirá en ningún punto predecible porque depende de lo que esté haciendo el usuario. Por ejemplo, si el usuario está escuchando el iPod, hay menos memoria disponible y la recibirá antes.

La regla general es que tiene aproximadamente 8 MB de RAM para trabajar. Cuando te acercas a eso, puedes esperar que el evento se eleve. Si está ocupando esa cantidad de RAM deliberadamente, debe tener un plan para hacer algo al respecto.

4

ACTUALIZACIÓN A partir de iOS 6, UIViewController vistas ya no se descargan en respuesta a las advertencias de memoria. En su lugar, haga todo lo posible para liberar los recursos que pueda recrear de manera razonable (por ejemplo, datos en caché) cuando se llame al didReceiveMemoryWarning.

ACTUALIZACIÓN
escribí mi respuesta original cuando era un hombre joven enojado; los tiempos han cambiado y, básicamente, está mal.

Si tiene una aplicación con un controlador de vista única y recibe una advertencia de memoria, no hay mucho que pueda hacer. Pero las cosas cambian drásticamente si tiene múltiples controladores de visualización, ya que puede descargar todos los el estado asociado con los controladores que no son frontales. De hecho, [UIViewController didReceiveMemoryWarning] lo empujará en la dirección correcta al descargar sus vistas no visibles para usted (¡sorpresa!). Cuando se descarta el controlador de vista frontal, la vista subyacente se vuelve a cargar y, como máximo, el usuario solo debe tener en cuenta una demora, aunque internamente su aplicación haya realizado un reinicio completo.

Este no es un detalle que pueda actualizar fácilmente, debe tener en cuenta el uso de la memoria desde el principio y diseñar su aplicación multivista en piezas UIViewController limpiamente descargables. De hecho, vale la pena mantener el código compatible con el simulador solo para utilizar su función de advertencia de memoria.

Cuando la memoria es abundante, no se descarga nada y todo es sedoso, y cuando la memoria es baja las cosas siguen funcionando, aunque más lentamente. Ahora diría que esta solución para el problema de la memoria finita es ideal.

Para tomar ventaja de este truco de salón de memoria, la sobrecarga de los métodos UIViewController viewDidLoad, viewDidUnload y viewWillUnload (IOS5, útil si la descarga del estado requiere que su objeto de mejorar aún existen, por ejemplo, si no desea que se escape el OpenGL texturas & búfer de renderizado, en iOS4 puedes simular esto sobrecargando didReceiveMemoryWarning y rastreando la visibilidad de tu vista).

ORIGINAL, respuesta más bilioso

didReceiveMemoryWarning es absolutamente inútil.

No hay garantía de que si liberas memoria (incluso toda) no te matarán.

En mi amarga experiencia por lo general funciona como este en 2.x/3.0:

  1. mediaserverd fugas de un montón de memoria

  2. mi aplicación es asesinado

Desafortunadamente , el segador nunca piensa en matar a mediaserverd.

Así que si el uso de la memoria no es su culpa, que realmente sólo tiene dos opciones:

  1. pedir al usuario que reinicie (usuario asume que es tu culpa, escribe una reseña mordaz)

  2. esperan los accidentes culpable (mediaserverd menudo obliga!)

+0

El tiempo avanza. viewDidUnload ahora está en desuso con estas notas, "Las vistas ya no se purgan en condiciones de poca memoria y nunca se llama a este método". y "En iOS 6 y posterior, borrar referencias a vistas y otros objetos en su controlador de vista es innecesario."- [fuente] (https://developer.apple.com/reference/uikit/uiviewcontroller/1621383-viewdidunload?language=objc) – jk7

+0

¡Estaba pensando en actualizar esta respuesta el otro día! –

5

Si el usuario dejado algunas aplicaciones abiertas que tendrá muy poca memoria a su dispos Alabama. Por lo tanto, el sistema puede llamar a veces didReceiveMemoryWarning solo después de 1 MB de uso.

El sistema llama a este método en todos sus controladores de vista, si coloca un NSLog en cada uno de sus controladores de vista, lo notará.

Luego, el sistema llamará automáticamente al método viewDidUnload en todos sus controladores de visualización (no en dealloc). Entonces debes poner todas tus instrucciones de desasignación allí.

Tienes que hacer muchos experimentos porque si tu aplicación es compleja te enfrentarás a muchos bloqueos antes de manejarla bien.

Cuestiones relacionadas