mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-17 08:01:27 +00:00
Ensure observeValueForKeyPath:ofObject:change:context is called consistently.
During the "normal" callback for new and old values, the ofObject: parameter passed to the observer is the original receiver of the addObserver:forKeyPath:options:context: call, but that isn't the case with the call caused by the CPKeyValueObservingOptionInitial option. This commit uses _targetObject, the receiver of the addObserver:... call, rather than self, the _CPKVOProxy.
This commit is contained in:
@@ -360,7 +360,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
|
||||
newValue = [CPNull null];
|
||||
|
||||
var changes = [CPDictionary dictionaryWithObject:newValue forKey:CPKeyValueChangeNewKey];
|
||||
[anObserver observeValueForKeyPath:aPath ofObject:self change:changes context:aContext];
|
||||
[anObserver observeValueForKeyPath:aPath ofObject:_targetObject change:changes context:aContext];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
@import <Foundation/CPKeyValueObserving.j>
|
||||
|
||||
@implementation CPKeyValueObservingTest : OJTestCase
|
||||
{
|
||||
CPString _lastKeyPath;
|
||||
id _lastObject;
|
||||
CPDictionary _lastChange;
|
||||
id _lastContext;
|
||||
}
|
||||
|
||||
- (void)setup
|
||||
{
|
||||
_lastKeyPath = _lastObject = _lastChange = _lastContext = nil;
|
||||
}
|
||||
|
||||
- (void)testInitialObserving
|
||||
{
|
||||
var tester = [ObservingTester testerWithCheese:@"CHEESE!"];
|
||||
[tester addObserver:self forKeyPath:@"cheese" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionInitial context:nil];
|
||||
|
||||
[self assert:@"cheese" equals:_lastKeyPath];
|
||||
[self assert:tester equals:_lastObject];
|
||||
[self assert:[CPDictionary dictionaryWithObject:@"CHEESE!" forKey:CPKeyValueChangeNewKey] equals:_lastChange];
|
||||
[self assert:nil equals:_lastContext];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(CPString)aKeyPath
|
||||
ofObject:(id)anObject
|
||||
change:(CPDictionary)aChange
|
||||
context:(id)aContext
|
||||
{
|
||||
_lastKeyPath = aKeyPath;
|
||||
_lastObject = anObject;
|
||||
_lastChange = aChange;
|
||||
_lastContext = aContext;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ObservingTester : CPObject
|
||||
{
|
||||
id cheese;
|
||||
}
|
||||
|
||||
+ (id)testerWithCheese:(id)aCheese
|
||||
{
|
||||
var tester = [[self alloc] init];
|
||||
[tester setCheese:aCheese];
|
||||
return tester;
|
||||
}
|
||||
|
||||
- (void)setCheese:(id)aCheese
|
||||
{
|
||||
cheese = aCheese;
|
||||
}
|
||||
|
||||
- (id)cheese
|
||||
{
|
||||
return cheese;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user