objective-c ios key-value-observing

objective c - KVO-¿Cómo verificar si un objeto es un observador?



objective-c ios (2)

[...] ¿es posible verificar si un objeto realmente está observando esa propiedad?

No. Cuando se trata de KVO, siempre debe tener el siguiente modelo en mente:

Al establecer una observación, usted es responsable de eliminar esa observación exacta. Una observación se identifica por su contexto; por lo tanto, el contexto debe ser único. Al recibir notificaciones (y, en Lion, al eliminar al observador), siempre debe probar el contexto, no la ruta.

La mejor práctica para manejar objetos observados es eliminar y establecer la observación en el colocador del objeto observado:

static int fooObservanceContext; - (void)setFoo:(Foo *)foo { [_foo removeObserver:self forKeyPath:@"bar" context:&fooObservanceContext]; _foo = foo; // or whatever ownership handling is needed. [foo addObserver:self forKeyPath:@"bar" options:0 context:&fooObservanceContext]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == &fooObservanceContext) { // handle change } else { // not my observer callback [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (void)dealloc { self.foo = nil; // removes observer }

Cuando use KVO, debe asegurarse de que ambos objetos, el observador y el observado, estén vivos siempre que la observación esté en su lugar.

Al agregar una observación, debe equilibrar esto con exactamente una eliminación de la misma observación. No asuma, usted es el único que usa KVO. Las clases de Framework pueden usar KVO para sus propios fines, de modo que siempre verifique el contexto en la devolución de llamada.

Un último aspecto que me gustaría señalar: la propiedad observada debe ser compatible con KVO. No puedes simplemente observar cualquier cosa .

Al observar un valor en un objeto usando addObserver:forKeyPath:options:context: eventualmente querrá llamar a removeObserver:forKeyPath: sobre ese objeto para limpiarlo más tarde. Sin embargo, antes de hacerlo, ¿es posible verificar si un objeto realmente está observando esa propiedad?

Intenté asegurar en mi código que un objeto solo tiene un observador eliminado cuando es necesario, pero hay algunos casos en los que es posible que el observador intente eliminarse dos veces. Estoy trabajando para evitar esto, pero por si acaso, he estado tratando de averiguar si hay una forma de verificar primero si mi código realmente es un observador de algo.


Parte del protocolo NSKeyValueObserving es este:

- (void *)observationInfo

que debería enumerar a los observadores.

EDIT Útil para la depuración solamente.