2012-09-26 20 views
47

Tal vez esta es una mala práctica, pero de las documentaciones que he leído recibí el consejo de inicializar objetos en algunos casos dentro del método viewDidLoad y nada en viewDidUnload.iOS6 viewDidUnload Obsoleto

Por ejemplo, si tiene algo así como la adición de un Observador

[[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(filterready:) 
               name:@"filterReady" 
               object:nil]; 

Ahora no tengo un método para eliminar el observador, sin embargo, el viewDidLoad convierte llamado cada vez que se muestra la vista que se traduce en tener múltiples los observadores se ejecutan después de un tiempo y el selector se llama varias veces.

Puedo solucionar esto moviendo algunos limpiadores al método viewDidDisappear, pero ahora tengo algunas dudas si estoy haciendo lo correcto.

En mi muestra que tiene varios controladores de navegación que están controlando sus subnavigations, pero el dealloc nunca es llamado por ellos, a pesar de que no se hace referencia

Respuesta

89

Se debe utilizar la - (void)didReceiveMemoryWarning y - (void)dealloc métodos.

En iOS 6, los métodos viewWillUnload y viewDidUnload de UIViewController ahora están en desuso. Si usaba estos métodos para liberar datos, use el método didReceiveMemoryWarning. También puede usar 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.

lo que debe comprobar si su vista está en la ventana, y luego retire el observador en la didReceiveMemoryWarning

+0

Probablemente sea la respuesta correcta. Aún así es extraño, que hayan eliminado este mensaje. Aprendí usando el SDK siguiendo las diapositivas de Paul Hegarty, y por supuesto todavía están para iOS5. Voy a verificar sus diapositivas actualizadas este año, tal vez él está dando una buena pista sobre esto. – Hons

+2

@Hons no es nada extraño: 'viewDidUnload' fue, explícitamente según la documentación, invocado solo si su vista está descargada debido a una advertencia de memoria. Si agrega un observador dentro de 'viewDidLoad' y lo elimina solo en' viewDidUnload', la mayor parte del tiempo será desasignado sin eliminarlo. Eso dejará un puntero colgando en el centro de notificaciones que casi con certeza provocará un bloqueo más adelante. – Tommy

+0

¿Cómo verifica si su vista está en la ventana? – zakdances

4

¿Por qué no eliminar el observador en la función DEALLOC? Y si está utilizando ARC, no llame a [super dealloc]

Si ve que la función dealloc del controlador no se está llamando, entonces debe descubrir por qué ocurre esto. Tal vez tenga un NSTimer ejecutándose en ViewController y cuando muestre la vista, esto haría que dealloc no sea llamado. O la vista se conserva en otro lugar.

+0

todo el punto de viewDidUnload es que se puede descargar la vista y liberar cosas para ahorrar memoria mientras que el controlador de vista todavía existe – user102008

+0

En iOS 6, los métodos y viewWillUnload viewDidUnload de UIViewController ahora están en desuso .... –

+0

Por lo tanto usted no debe no use el método dealloc Porque el objeto no está listo para ser destruido aún. – Craimasjien

9

Alex respuesta es buena. Pero me gusta el emparejamiento adecuado. Por esa razón, a menos que la vista tiene que ser notificado cuando ni siquiera es visto, Yo suelo añadir notificación en viewWillAppear y viewDidDisappear

+0

viewDidUnload se invoca cuando la vista se descarga y viewDidDisappear justo cuando la vista ha desaparecido. Las notificaciones que no se han registrado en el método viewDidUnload, ahora, desde iOS 6.0, deben anularse con didReceiveMemoryWarning o dealloc –

12

En primer lugar, incluso cuando viewDidUnload no se desaprobó, usted debe haber tenido que anular el registro que la notificación en viewDidUnload Y dealloc. Incluso antes de iOS 6, viewDidUnload NO se llama en la mayoría de las circunstancias; solo en situaciones de poca memoria. Entonces, si solo lo hubiera puesto en viewDidUnload y no en dealloc anteriormente, no se habría desregistrado, y probablemente se habría bloqueado cuando se lo desasignó y recibió una notificación. Entonces debe haber tenido que ponerlo en dealloc antes, para que haya funcionado correctamente.

En segundo lugar, si lo hizo correctamente antes, no necesita hacer nada adicional para que funcione correctamente en iOS 6. La única diferencia en iOS 6 es que las vistas ya no se descargan en absoluto (incluso en baja situaciones de memoria). Por lo tanto, es lo mismo que en iOS 5 cuando no se encontraba en una situación de poca memoria. Como las vistas no están descargadas, viewDidLoad solo se llamará una vez, por lo que su notificación solo se registrará una vez.No se registrará en dealloc, ya que debe haberlo configurado para que haya funcionado correctamente.

Cuestiones relacionadas