I have one managed object with a one-to-many relationship to member class. When I add the observers for members, it worked. When one new member is added to the relationship, the observeValueForKeyPath will be invoked with the new object and change dictionary contains the new member object. However, observeValueForKeyPath will be triggered second time with all values nil and change dictionary new="NULL". What is the second trigger? I set a breakpoint, but not sure who made the trigger.
@interface FooObject : NSManagedObject {}
@property (nonatomic, strong) NSString *fooId;
@property (nonatomic, strong) NSSet* members;
@end
@implementation FooObject
@dynamic fooId;
@dynamic members;
- (NSMutableSet*)membersSet {
[self willAccessValueForKey:@"members"];
NSMutableSet *result = (NSMutableSet*)[self mutableSetValueForKey:@"members"];
[self didAccessValueForKey:@"members"];
return result;
}
- (void)registerObservers {
[self addObserver:self
forKeyPath:@"members"
options:NSKeyValueObservingOptionNew
context:nil];
}
- (void)unregisterObservers {
@try{
[self removeObserver:self forKeyPath:@"members"];
}@catch(id anException){
//do nothing, obviously it wasn't attached because an exception was thrown
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
id valueNewSet = [change objectForKey:NSKeyValueChangeNewKey];
if (![valueNewSet isKindOfClass:[NSSet class]]) {
// not a NSSet, it contains <null> value
NSLog(@"%@", change);
NSLog(@"%@", object);
}
if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeInsertion) {
// insert change is valid, process the changes
}
}
@end
Log output:
{
kind = 1;
new = "<null>";
}
<FooObject: 0xfa9cc60> (entity: FooObject; id: 0xfa9be00 <x-coredata://39DB31FD-6795-4FDE-B700-819AB22E5170/SHInterest/p6> ; data: {
fooId = nil;
members = nil;
})
EDIT 1 I set a breakpoint at NSLog(@"%@", change); This is the stack trace but not really helpful to figure who makes this call.
main -> UIApplicationMain -> NSKeyValueNotifyObserver -> observeValueForKeyPath:ofObject:change:context
EDIT 2 Maybe this is still a bug? http://www.cocoabuilder.com/archive/cocoa/182567-kvo-observevalueforkeypath-not-reflecting-changes.html