2012-09-27 14 views
6

Trabajo como parte de un gran equipo que trabaja con el código heredado iOS con un entorno iOS objetivo de 4.3 y posterior. He visto a otros desarrolladores verificar las clases que descienden de NSObject pero no tienen un método dealloc. También he visto UIViewController descendientes que no incluyen los métodos viewDidUnload. Cuando pregunto sobre este código, la respuesta habitual es "No se preocupe, ARC se encarga de eso ahora".¿Todavía se requieren métodos 'dealloc' y 'viewDidUnload' cuando se usa ARC, antes de iOS6?

entiendo que viewDidUnload se llama cuando las condiciones de memoria iOS experiencias bajas, con el objetivo de liberar espacio en la memoria por la liberación de los objetos que se pueden recrear llamando viewDidLoad, y que dealloc es llamado cuando la cuenta de retención de un objeto llega a cero. Para los objetos y descendientes de UIViewController esto puede significar que 'viewDidUnload' se llame o no antes de dealloc.

Así que aquí está mi pregunta: ¿Todavía se requieren métodos dealloc y viewDidUnload al usar ARC en las versiones de iOS anteriores a iOS 6?

Si la respuesta es "Sí!" entonces necesitaré buenas razones y/o documentación para llevar el argumento.

Esperamos sus respuestas. (Gracias a Tommy por ayudarme a ajustar mi pregunta.)

Respuesta

14

viewDidUnloadis deprecated. Entonces, independientemente de ARC, no solo no necesita uno sino que no debe usar uno. La justificación establecida es que las vistas ya no se purgan en advertencias de memoria baja (presumiblemente porque ahora contribuyen demasiado poco al total como para que valga la pena de respuesta); No me sorprendería si parte de la justificación fuera que mucha gente asumió que podría liberar todos los recursos creados en viewDidLoad dentro de y eso solo evitaría fugas. Eso no es cierto porque viewDidUnload es llamado solo si la vista está descargada debido a una advertencia de memoria baja. No se llama en el ciclo de vida normal.

Bajo ARC's new rules:

Es posible aplicar un método dealloc si es necesario gestionar los recursos distintos de la liberación de las variables de instancia. Usted no tiene que (en realidad no se puede ) liberar variables de instancia

EDIT: a comentar específicamente 4.3+ ...

ARC no implementará una versión de viewDidUnload para usted.El objetivo del ciclo viewDidLoad/viewDidUnload era que si usted retain cualquier parte de la jerarquía de vista por algún motivo, provocaría que no se liberara automáticamente en una advertencia de memoria baja, pero al hacerlo no le comprará ningún beneficio porque tan pronto como se cargue la vista lo que retengas será reemplazado por una nueva copia. Por lo tanto, si tiene strongIBOutlet s para las vistas que están dentro de la jerarquía debajo de self.view, entonces idealmente las eliminaría durante viewDidUnload. Incluso si tiene weak referencias que es un buen lugar para evitar seguir adelante con cualquier punteros colgantes.

A partir de iOS 5 puede tener referencias débiles de puesta a cero automática, por lo que usarlas y no implementar viewDidUnload sería el camino a seguir si estuviera apoyando 5+. Para 4.3 si utiliza referencias fuertes y omite viewDidUnload, puede terminar impidiendo una respuesta tan exhaustiva a una advertencia de poca memoria como le gustaría a Apple, pero no perderá memoria. Si usa referencias débiles, deberá ser un poco cuidadoso al no hacer referencia a ninguno de esos objetos cuando no tenga una vista (es decir, cada vez que no se encuentre en pantalla pero la vista haya sido cargada previamente). en el controlador que también ajusta una vista, pero que se ven afectados por otro, son un ejemplo clásico, como por ejemplo, si estaba actualizando un campo mediante la observación del valor de la clave).

Puede usar el simulador 'Simulate Memory Warning' para probar y depurar ese material hasta cierto punto.

El dealloc que proporciona ARC será el mismo independientemente de la versión de iOS. Sin embargo, cubrirá solo objetos Objective-C. Cuando dicen que no pueden liberar variables de instancia, lo dicen en el sentido literal de enviarles el mensaje release. Supongamos que tiene objetos Core Foundation o que ha realizado una asignación pura de memoria C, entonces querrá implementar un dealloc que elimine todos esos.

Obviamente, los instrumentos y la herramienta de fugas son las formas de probar y depurar esa área; tenga cuidado siempre que se filtre la memoria para verificar si el tipo de objeto que creó esa memoria también se está filtrando. El objeto inmediato puede estar bien, pero sus asignaciones aparecerán en la lista filtrada si no fuera dealloc porque alguien más lo filtró.

+0

Lo sentimos, @Tommy, no estaba lo suficientemente claro en mi pregunta sobre la versión de iOS de destino. Actualizará la pregunta en función de su respuesta. :) – tychoD

+0

Gracias, eso respondió mi pregunta. : D – tychoD

+0

¿Tengo que anular todas mis @properties en dealloc()? –

6

viewDidUnload ahora está en desuso y ya no es llamado por el sistema (a partir de iOS 6). Nunca fue tan útil como esperaba Apple, y era más problemático de lo que valía. Esto no tiene nada que ver con ARC.

dealloc a menudo no es necesario en ARC, pero aún así es necesario en situaciones en las que necesita una gestión de recursos que no sea de ARC. Por ejemplo, si necesita usar free(), o de otra manera liberar un recurso. También es un buen lugar para retirarte como observador o delegado. Pero muchas clases ahora no requieren dealloc.

Cuestiones relacionadas