diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j index 86df9ed48..c05d791d9 100644 --- a/Foundation/CPKeyValueObserving.j +++ b/Foundation/CPKeyValueObserving.j @@ -71,6 +71,12 @@ + (BOOL)automaticallyNotifiesObserversForKey:(CPString)aKey { + var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substring(1), + selector = "automaticallyNotifiesObserversOf" + capitalizedKey; + + if ([[self class] respondsToSelector:selector]) + return objj_msgSend([self class], selector); + return YES; } diff --git a/Tests/Foundation/CPKeyValueObservingTest.j b/Tests/Foundation/CPKeyValueObservingTest.j index 2d409618f..55c9f5f9d 100644 --- a/Tests/Foundation/CPKeyValueObservingTest.j +++ b/Tests/Foundation/CPKeyValueObservingTest.j @@ -193,11 +193,37 @@ notSame:class_getInstanceMethod([object class], removeSelector)]; } +- (void)testAutomaticallyNotifiesObserversOf +{ + var test = [ObservingTester new]; + + [test addObserver:self forKeyPath:@"cheese" options:0 context:nil]; + [test addObserver:self forKeyPath:@"astronaut" options:0 context:nil]; + + // Cheese shouldn't have been affected. + [test setCheese:@"changed cheese"]; + [self assert:@"cheese" equals:_lastKeyPath] + [self assert:test equals:_lastObject]; + + // Cheese shouldn't have been affected. + [test setAstronaut:@"Armstrong"]; + // Nothing should have been observed because we don't automatically notify + // and we didn't call will/didChange. + [self assert:@"cheese" equals:_lastKeyPath message:"no observation when automatically notifies is off"]; + [self assert:test equals:_lastObject]; +} + @end @implementation ObservingTester : CPObject { id cheese; + id astronaut @accessors; +} + ++ (BOOL)automaticallyNotifiesObserversOfAstronaut +{ + return NO; } + (id)testerWithCheese:(id)aCheese