The NSKeyValueObserving
addition to NSObject
adds an observe message that takes an identifying context pointer – don't use NULL
in its place.
Your superclass may observe the same key path for the same object. You need to pass along its observations, and only take actions on yours. The context pointer distinguishes which observations are yours.
static void *kContext = &kContext;
// …
// alternatively, you could just use self as the context pointer
void *context = (__bridge void *) self;
[obj addObserver:self
forKeyPath:key
options:0
context:kContext]; // <-- context pointer
// …
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (context == kContext)
// do stuff
else
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
via Mike Ash's Defensive Programming in Cocoa talk – PDF.
Alternatively, you could use self
as the context pointer:
void *context = (__bridge void *) self;
[obj addObserver:self
forKeyPath:key
options:0
context:context];
// …
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (context != (__bridge void *)self) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
return;
}
// do stuff
}