2009-01-01 21 views
8

Tengo un caso en el que la vista secundaria envía notificaciones a su vista primaria. Ahora llamo al addObserver: en viewWillAppear: y removeObserver: en viewWillDisappear:. Pero, supongo que esto no es correcto ya que viewWillAppear: llama cuando la vista se actualiza.Posibles ubicaciones para llamar a los métodos addObserver y removeObserver

[[NSNotificationCenter defaultCenter] addObserver: (id)observer selector: (SEL)aSelector name: (NSString *)aName object: (id)anObject]; 

[[NSNotificationCenter defaultCenter] removeObserver: (id)observer name: (NSString *)aName object: (id)anObject]; 

Thanks.

Respuesta

5

En realidad, esta es una mala idea. Cuando la memoria baja, su controlador de vista puede recibir una advertencia de memoria. El comportamiento predeterminado en esta instancia es borrar su vista (si no está actualmente en la pantalla). En este caso, podría recibir el mensaje viewDidLoad enviado por segunda vez (después del evento de memoria, cuando su controlador de navegación vuelva a mostrar la vista en la pantalla). Así tendrá dos registros del mismo objeto, pero solo una eliminación (en su trato)

Una mejor solución es establecer un indicador que indique que se ha registrado, o registrarse en su método init.

+0

¿Es cierto que 'dealloc' no siempre se llama?¿Sería más seguro llamar a 'addObserver' en' init' y llamar a 'removeObserver' en' viewDidUnload', o este esquema provocaría que mi controlador de vista no se vuelva a registrar después de que se cargue nuevamente después de la advertencia de memoria (que causó la vista para descargarse ya que no se mostró)? – matm

+3

Aún no está claro dónde colocar el removeObserver en este caso. – Resh32

+1

recuerde que 'viewDidUnload' está en desuso desde iOS 6.0 ... – DanSkeel

1

Supongo que las posiciones correctas para registrarse para la notificación es viewDidLoad método, y la posición correcta para anular el registro de las mismas notificaciones es dealloc método.

+0

Pero cuando se recibe una advertencia de memoria, se llamará a viewDidUnload pero no a dealloc, cuando vuelva a iniciarse en este viewcontroller, se llamará a viewDidLoad nuevamente, luego, su aviso se registrará nuevamente. – ZYiOS

+1

Tienes razón. Esta publicación es muy antigua, así que ignórala. Lo importante es equilibrar el registro y anular el registro de llamadas. Utilice viewDidLoad y viewDidUnload, o viewDidLoad (con flag) y dealloc, o init y dealloc para registrar y anular el registro de sus notificaciones. Ver el comentario de Ben Gottlieb para información relevante. – Mustafa

+0

No sé si es correcto tampoco, pero lo hago a tu manera. Y recuerde que viewDidUnload está en desuso desde iOS 6.0 ... – DanSkeel

0

Ben tiene razón, pero encontré otra manera, potencialmente frágil, de evitarlo. Acabo de descubrir esto porque siempre obtenía el "... se desasignó mientras los observadores de valores clave todavía estaban registrados con él"

No sé por qué, pero cuando tenía addObserver en mi método init, y removeObserver en mi método dealloc - todavía estaba recibiendo el mensaje KVO todavía se estaba observando. Di un paso y verifiqué que mi removeObserver se llamaba correctamente.

Moví mi addobserver en el método viewDidLoad y pareció funcionar.

Dejé un removeObserver en viewDidUnload y en dealloc; pero no me gusta porque no está equilibrado. Pero en circunstancias normales, mi viewDidUnload no se llama, esto es solo protección en caso de recibir una notificación de poca memoria.

Pero puedo ver potencialmente entrar en la situación en la que aparece un evento de poca memoria, se llama a viewDidUnload. Si luego presiono dealloc en algún momento después de eso (antes de presionar viewDidLoad nuevamente), ¡llamaré a removeObserver dos veces!

Por lo tanto, creo que lo mantendré en mi viewDidLoad, y mi dealloc.

Todavía no sé por qué no funciona bien si hago el addobserver en mi método init.

Cuestiones relacionadas