Cuando me he registrado un objeto foo para recibir las notificaciones MVA de otro objeto barra de (usando addObserver: ...), si a continuación, DEALLOCATE foo necesito para enviar un mensaje a removeObserver:forKeyPath:
barra de en -dealloc?En Cocoa, ¿necesito eliminar un Objeto de recibir notificaciones KVO al desasignarlo?
Respuesta
Necesita usar -removeObserver:forKeyPath:
para eliminar el observador antes de ejecutar -[NSObject dealloc]
, entonces sí, hacerlo en el método -dealloc
de su clase funcionaría.
Mejor que eso sería tener un punto determinista donde lo que posee el objeto que está haciendo la observación podría decir que está hecho y (eventualmente) será desasignado. De esta forma, puede dejar de observar inmediatamente cuando ya no se necesita lo que está haciendo la observación, independientemente de cuándo se desasigna.
Esto es importante tener en cuenta porque la vida útil de los objetos en Cocoa no es tan determinista como algunas personas parecen pensar que es. Los diversos frameworks de Mac OS X en sí mismos serán y enviarán sus objetos -retain
y -autorelease
, extendiendo su vida más allá de lo que de otro modo podrían pensar que sería.
Por otra parte, cuando se hace la transición a la recolección de basura de Objective-C, usted encontrará que -finalize
se ejecutará en momentos muy diferentes - y en muy diferentes contextos - -dealloc
que lo hicieron. Por un lado, la finalización tiene lugar en un hilo diferente, por lo que realmente no puede enviar de forma segura -removeObserver:forKeyPath:
a otro objeto en un método -finalize
.
palillo de la memoria (y otros recursos escasos) en la gestión -dealloc
y -finalize
, y utilizar un método separado -invalidate
tener un propietario indicar a un objeto que haya terminado con él en un punto determinista; hacer cosas como eliminar las observaciones de KVO allí. La intención de su código será más clara y tendrá menos errores sutiles de los que ocuparse.
Un poco de información extra que he obtenido por experiencia dolorosa: aunque NSNotificationCenter usa referencias débiles de puesta a cero cuando se ejecuta en la recolección de basura, KVO no lo hace. Por lo tanto, puede salirse con la suya si no utiliza un observador NSNotificationCenter cuando usa GC (cuando usa retener/liberar, aún necesita quitar su observador), pero igual debe eliminar sus observadores de KVO, como describe Chris.
está documentado el lugar? – hpique
Definitivamente estoy de acuerdo con Chris en el comentario "Stick to memory (y otros recursos escasos) en -dealloc and -finalize ...". Muchas veces veré que las personas intentan invalidar los objetos NSTimer en sus funciones dealloc. El problema es que NSTimer retiene sus objetivos. Entonces, si el objetivo de ese NSTimer es uno mismo, dealloc nunca será llamado, lo que dará como resultado pérdidas de memoria potencialmente desagradables.
Invalidate en -invalidate
y hacer otra limpieza de la memoria en su dealloc
y finalize.
- 1. Recibir notificaciones cuando la aplicación actual cambie en Cocoa
- 2. Herramienta para depurar KVO/enlaces en Cocoa
- 3. ¿Cómo puedo recibir notificaciones sobre un cambio de horario del sistema en mi aplicación Cocoa?
- 4. KVO: ¿Puedo eliminar todos los observadores del objeto concreto
- 5. Implementando un puente-patrón compatible con KVO/Bindings en Cocoa
- 6. KVO en UIViewController matriz childViewControllers
- 7. Notificaciones push de Apple: al registrarse para recibir notificaciones, no se reciben devoluciones de llamadas
- 8. Recibir notificaciones push en PhoneGap para iOS
- 9. iOS: cómo registrarse para recibir notificaciones push?
- 10. Recibir notificaciones cuando se reproduce un sonido en OpenAL
- 11. Recibir notificaciones con la aplicación en el modo de fondo
- 12. KVO para propiedades de objetos enteros
- 13. KVO - ¿Cómo comprobar si un objeto es un observador?
- 14. Recibir encabezados HTTP a través de NSURLRequest/NSURLConnection en Cocoa
- 15. NSUserDefaults and KVO issues
- 16. ¿Cómo recibir notificaciones automáticas de mi cuenta de Gmail?
- 17. knockoutjs: cómo recibir notificaciones para todas las propiedades una vez
- 18. ¿Es posible utilizar KVO en AVPlayerItem.loadedTimeRanges?
- 19. ¿Cómo recibir notificaciones de una vista emergente en UINavigationController?
- 20. Objetivo C: recibir notificaciones sobre el estado inactivo de un usuario
- 21. Eliminar notificaciones de la barra de notificaciones de otras aplicaciones
- 22. ¿Cómo recibir notificaciones cuando una ventana se enfoca en WPF?
- 23. ¿Cómo recibir notificaciones cuando finaliza una construcción exitosa?
- 24. ¿cómo recibir notificaciones de cambio de volumen de medios?
- 25. ¿Al usar KVO es necesario eliminar a uno mismo como un observador de sí mismo en -dealloc?
- 26. ¿Cómo recibir notificaciones para eventos de tarjetas SD?
- 27. Cómo eliminar un objeto en un conjunto
- 28. Eliminar un objeto de imagen
- 29. ¿Cómo puedo recibir notificaciones cuando se visualice UIView?
- 30. Javascript Eventos: recibir notificaciones de cambios en un valor <input> de control
puedo confirmar por experiencia que el dolor que va a recibir en un sinfín de accidentes si no se retiran a sus observadores. – Jeff
¡Gracias por esa minuciosa explicación! –
A partir de OS X 10.7 Lion, también hay '-removeObserver: forKeyPath: context:', que le permite pasar en el mismo contexto que pasó a '-addObserver: forKeyPath: options: context:'. Pasar un contexto único garantiza que no eliminará la observación de otra persona cuando elimine la suya.En caso que –