2012-04-06 17 views
16

lo general el uso NSNotification como el ejemplo siguiente:que es una mejor manera de eliminar observador Notificación

En viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:kName1 object:nil]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bar:) name:kName2 object:nil]; 

En viewDidUnload y dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

Pero un amigo me dijo que no debería usar [[NSNotificationCenter defaultCenter] removeObserver:self]; porque eliminará todos los observadores, incluida la superclase. Me sugirió que usara el siguiente código para eliminar al observador uno por uno.

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil]; 
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName2 object:nil]; 

He comprobado el código de la biblioteca ASIHttpRequest (https://github.com/pokeb/asi-http-request). Sigue la sugerencia de mis amigos.

Quiero saber si mi amigo tiene razón o no? En mi opinión, dado que la instancia actual será descarga o dealloc, la notificación de la superclase también es inútil. ¿Y hay alguna notificación de uso de la subclase UIViewController del sistema?

+0

¿Qué significa que eliminará el "observador de superclase"? Un observador es una instancia de objeto, no una clase. Si se va a desasignar, debe anular el registro de todas las notificaciones, incluso si se registraron en el código de la superclase. – MrTJ

+0

@MrTJ Me refiero al observador de notificación que se agrega en el método de super. Quizás el padre de la instancia de clase también necesite observar algunas notificaciones cuando se llama al método viewDidUnload del niño. – tangqiaoboy

+0

Podría ser, podría ser.Si desea cancelar el registro en viewDidUnload, entonces para seguridad también le sugiero usar el segundo método (por anulación de registro de observador) – MrTJ

Respuesta

12

Tu amigo es 100% correcto. Sin embargo, no importa si elimina todas las observaciones de notificación en dealloc.
Mencionó viewDidUnload, y el caso es completamente diferente, porque el objeto descargado permanecerá activo, y no sabe cuándo se vuelven a agregar las observaciones de notificación de la superclase. Si se agregan en viewDidLoad, no tendrás problemas. Si se agregan en un método init, usted acaba de perder un montón de observaciones de notificación importantes.

La eliminación de observaciones con nombres específicos es una buena práctica y se debe hacer desde el principio.

+0

Gracias. Entonces podemos usar '[[NSNotificationCenter defaultCenter] removeObserver: self];' en el método 'dealloc', pero NO en el método' viewDidUnload', ¿verdad? – tangqiaoboy

+0

Sí, 'removeObserver:' no se debe usar fuera de dealloc. Pero me gusta eliminar cada observación específicamente a mí mismo, por lo que no uso 'removeObserver:' en absoluto. Utilizo el método específico 'removeObserver: name: object:' para todas mis notificaciones. Me gusta mantener mi código muy específico. –

7

Cuando se desea eliminar todas las notificaciones que utilice,

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

Si desea eliminar una notificación especial que utiliza,

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil]; 

Cuando ya no necesita de ninguna notificación de la primera el enfoque es simple.

0

Utilizo la primera manera, nunca pensé si era correcto o no. Si se llama a dealloc, entonces el objeto (súper también) será desasignado de todos modos. Lo que definitivamente NO quieres es que NSNotification se envíe a una instancia desasignada.

1

Como el objeto se va, es seguro usar [[NSNotificationCenter defaultCenter] removeObserver:self]; en el método dealloc.

En el método ViewDidUnload, será mejor que elimine a cada observador uno por uno como referencia de que el controlador todavía está presente (y su correspondiente viewDidLoad debería volver a agregarlos).

Cuestiones relacionadas