Tengo una clase C objetiva. En él, creé un método init y configuré una NSNotification en él
//Set up NSNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getData)
name:@"Answer Submitted"
object:nil];
¿Dónde configuro el [[NSNotificationCenter defaultCenter] removeObserver:self]
en esta clase? Sé que para a UIViewController
, puedo agregarlo al viewDidUnload
método. Entonces, ¿qué se debe hacer si acabo de crear una clase c objetiva?
-(void)dealloc
y luego agregarloremoveObserser:self
. Esta es la forma más recomendada de ponerremoveObservers:self
dealloc
método en iOS 6?Respuestas:
La respuesta genérica sería "tan pronto como ya no necesite las notificaciones". Obviamente, esta no es una respuesta satisfactoria.
Le recomiendo que agregue una llamada
[notificationCenter removeObserver: self]
al métododealloc
de esas clases, que tiene la intención de usar como observadores, ya que es la última oportunidad para anular el registro de un observador limpiamente. Sin embargo, esto solo lo protegerá contra fallas debido a que el centro de notificaciones notifica objetos muertos. No puede proteger su código contra la recepción de notificaciones, cuando sus objetos aún no están / ya no están en un estado en el que puedan manejar correctamente la notificación. Para esto ... Ver arriba.Editar (ya que la respuesta parece generar más comentarios de los que hubiera pensado) Todo lo que estoy tratando de decir aquí es: es realmente difícil dar consejos generales sobre cuándo es mejor eliminar al observador del centro de notificaciones, porque eso depende:
Entonces, el mejor consejo general que se me ocurre: proteger su aplicación. contra al menos un posible fracaso,
removeObserver:
bailadealloc
, ya que ese es el último punto (en la vida del objeto), donde puedes hacerlo limpiamente. Lo que esto no significa es: "solo posponga la eliminación hasta quedealloc
se llame, y todo estará bien". En su lugar, elimine al observador tan pronto como el objeto ya no esté listo (o no sea necesario) para recibir notificaciones . Ese es el momento exacto. Desafortunadamente, al no conocer las respuestas a ninguna de las preguntas mencionadas anteriormente, ni siquiera puedo adivinar cuándo sería ese momento.Siempre puede utilizar
removeObserver:
un objeto de forma segura varias veces (y todas menos la primera llamada con un observador determinado serán nops). Entonces: piense en hacerlo (nuevamente)dealloc
solo para estar seguro, pero ante todo: hágalo en el momento apropiado (que está determinado por su caso de uso).fuente
dealloc
es solo una última línea de defensa contra el bloqueo de la aplicación debido a un acceso posterior a un objeto descalificado. Pero el lugar adecuado para anular el registro de un observador suele ser otro lugar (y, a menudo, mucho antes en el ciclo de vida del objeto). No estoy tratando de decir aquí "Oye, hazlodealloc
y todo saldrá bien".viewWillDisappear
" El problema de dar un consejo concreto es que realmente depende de qué tipo de objeto registre como observador para qué tipo de evento. Se puede ser la solución correcta para anular el registro de observador enviewWillDisappear
(oviewDidUnload
) paraUIViewController
s, pero que realmente depende del caso de uso.Nota: Esto ha sido probado y funciona al 100%.
Rápido
PresentadoViewController
C objetivo
En
iOS 6.0 > version
, es mejor eliminar al observadorviewWillDisappear
ya que elviewDidUnload
método está en desuso.Muchas veces es mejor
remove observer
cuando la vista se ha eliminado delnavigation stack or hierarchy
.PresentadoViewController
fuente
viewWillAppear:
removeObserver:self
a cualquiera de losUIViewController
eventos del ciclo de vida arruinará su semana. Más lectura: subjetivo-objetivo-c.blogspot.com/2011/04/…removeObserver
llamadasviewWillDisappear
como se indica es definitivamente el camino correcto si el controlador se presenta a través depushViewController
. Si los coloca en sudealloc
lugardealloc
, nunca se llamará, al menos en mi experiencia ...Desde iOS 9 ya no es necesario eliminar observadores.
https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/index.html#10_11NotificationCenter
fuente
Si el observador se agrega a un controlador de vista , recomiendo encarecidamente agregarlo
viewWillAppear
y eliminarloviewWillDisappear
.fuente
viewWillAppear
yviewWillDisappear
para viewControllers?dealloc
una llamada inmediata. Volver al controlador de vista puede causar múltiples notificaciones si se agrega observador en los comandos de inicialización.fuente
self
after[super dealloc]
me pone nervioso ... (incluso si es poco probable que el receptor elimine la referencia del puntero de alguna manera, bueno, nunca se sabe cómo se implementaronNSNotificationCenter
)[super dealloc]
debe ser siempre la última declaración de sudealloc
método. Destruye tu objeto; después de que se ejecute, ya no tendrá unself
archivo. / cc @Dirk[super dealloc]
ya no es necesarioEn general, lo pongo en el
dealloc
método.fuente
En uso rápido deinit porque dealloc no está disponible:
Documentación rápida:
fuente
* editar: este consejo se aplica a iOS <= 5 (incluso allí debería agregar
viewWillAppear
y eliminarviewWillDisappear
, sin embargo, el consejo se aplica si por alguna razón ha agregado el observadorviewDidLoad
)Si ha agregado el observador en
viewDidLoad
, debe eliminarlo en ambosdealloc
yviewDidUnload
. De lo contrario, terminará agregándolo dos veces cuandoviewDidLoad
se llame despuésviewDidUnload
(esto sucederá después de una advertencia de memoria). Esto no es necesario en iOS 6, dondeviewDidUnload
está obsoleto y no se llamará (porque las vistas ya no se descargan automáticamente).fuente
En mi opinión, el siguiente código no tiene sentido en ARC :
En iOS 6 , tampoco tiene sentido eliminar observadores
viewDidUnload
, porque ahora ha quedado obsoleto.En resumen, siempre lo hago
viewDidDisappear
. Sin embargo, también depende de sus requisitos, como dijo @Dirk.fuente
¡Creo que encontré una respuesta confiable ! Tuve que hacerlo, ya que las respuestas anteriores son ambiguas y parecen contradictorias. Revisé libros de cocina y guías de programación.
Primero, el estilo de
addObserver:
inviewWillAppear:
yremoveObserver:
inviewWillDisappear:
no me funciona (lo probé) porque estoy publicando una notificación en un controlador de vista secundaria para ejecutar código en el controlador de vista principal. Solo usaría este estilo si estuviera publicando y escuchando la notificación dentro del mismo controlador de vista.La respuesta en la que más confiaré, la encontré en Programación de iOS: Guía de Big Nerd Ranch 4th. Confío en los chicos de BNR porque tienen centros de capacitación de iOS y no solo están escribiendo otro libro de cocina. Probablemente les conviene ser precisos.
Ejemplo uno de BNR:
addObserver:
eninit:
,removeObserver:
endealloc:
Ejemplo dos de BNR:
addObserver:
enawakeFromNib:
,removeObserver:
endealloc:
... cuando quitan al observador en
dealloc:
no usan[super dealloc];
Espero que esto ayude a la próxima persona ...
Estoy actualizando esta publicación porque Apple ahora se ha ido casi por completo con Storyboards, por lo que es posible que lo mencionado anteriormente no se aplique a todas las situaciones. Lo importante (y la razón por la que agregué esta publicación en primer lugar) es prestar atención si te
viewWillDisappear:
llaman. No fue para mí cuando la aplicación entró en segundo plano.fuente
La respuesta aceptada no es segura y podría provocar una pérdida de memoria. Por favor, deje la cancelación del registro en dealloc pero también cancele el registro en viewWillDisappear (eso es, por supuesto, si se registra en viewWillAppear) .... ¡ESO ES LO QUE HICE DE TODOS MODOS Y FUNCIONA MUY BIEN! :)
fuente
Es importante notar también que también
viewWillDisappear
se llama cuando el controlador de vista presenta una nueva UIView. Este delegado simplemente indica que la vista principal del controlador de vista no está visible en la pantalla.En este caso, desasignar la notificación en
viewWillDisappear
puede ser un inconveniente si usamos la notificación para permitir que UIview se comunique con el controlador de vista principal.Como solución, generalmente elimino al observador en uno de estos dos métodos:
Por razones similares, cuando emito la notificación por primera vez, debo tener en cuenta el hecho de que cada vez que aparece una vista sobre el controlador, se activa el
viewWillAppear
método. Esto, a su vez, generará copias múltiples de la misma notificación. Dado que no hay una forma de verificar si una notificación ya está activa, obvio el problema eliminando la notificación antes de agregarla:fuente
SWIFT 3
Hay dos casos de uso de notificaciones: - solo se necesitan cuando el controlador de vista está en la pantalla; - Son necesarios siempre, incluso si el usuario abrió otra pantalla sobre la corriente.
Para el primer caso, el lugar correcto para agregar y quitar observador es:
para el segundo caso, la forma correcta es:
Y nunca puso
removeObserver
endeinit{ ... }
- que es un error!fuente
fuente