From 6435372fd904e84c40b5286acc79dcd99e1a8647 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Fri, 25 Feb 2011 17:59:54 -0800 Subject: [PATCH] We weren't actually keeping track of replaced methods, and thus were replacing every time you call addObserver: --- Foundation/CPKeyValueObserving.j | 2 ++ Tests/Foundation/CPKVOTest.j | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j index a3ef96b07..6db7a6405 100644 --- a/Foundation/CPKeyValueObserving.j +++ b/Foundation/CPKeyValueObserving.j @@ -295,6 +295,8 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti if ([_replacedKeys containsObject:aKey] || ![_nativeClass automaticallyNotifiesObserversForKey:aKey]) return; + [_replacedKeys addObject:aKey]; + var theClass = _nativeClass, KVOClass = _targetObject.isa, capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substring(1); diff --git a/Tests/Foundation/CPKVOTest.j b/Tests/Foundation/CPKVOTest.j index 49bc9f617..55cde1709 100644 --- a/Tests/Foundation/CPKVOTest.j +++ b/Tests/Foundation/CPKVOTest.j @@ -440,6 +440,30 @@ [self assert:observationCount equals:3]; } +- (void)testSettersReplacedOnce +{ + var bob = [[PersonTester alloc] init], + betty = [CPObject new]; + + [bob addObserver:self forKeyPath:@"name" options:nil context:"testSettersReplacedOnce"]; + + var oldImp = class_getMethodImplementation(bob.isa, @selector(setName:)); + + [bob removeObserver:self forKeyPath:@"name"]; + + [bob addObserver:self forKeyPath:@"name" options:nil context:"testSettersReplacedOnce"]; + + var newImp = class_getMethodImplementation(bob.isa, @selector(setName:)); + + [self assertTrue:newImp === oldImp]; + + [bob addObserver:betty forKeyPath:@"name" options:nil context:"testSettersReplacedOnce"]; + + var newImp = class_getMethodImplementation(bob.isa, @selector(setName:)); + + [self assertTrue:newImp === oldImp]; +} + - (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)aContext { var oldValue = [changes objectForKey:CPKeyValueChangeOldKey],