diff --git a/AppKit/CPObjectController.j b/AppKit/CPObjectController.j index ebdfcb43e..bd1703113 100644 --- a/AppKit/CPObjectController.j +++ b/AppKit/CPObjectController.j @@ -459,13 +459,13 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo - (BOOL)isEqual:(id)anObject { - if ([anObject class] === [self class]) - { - if (anObject._observer === _observer && [anObject._keyPath isEqual:_keyPath] && [anObject._object isEqual:_object]) - return YES; - } + if (self === anObject) + return YES; - return NO; + if (!anObject || [anObject class] !== [self class] || anObject._observer !== _observer || anObject._keyPath !== _keyPath || anObject._object !== _object) + return NO; + + return YES; } - (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context @@ -808,15 +808,20 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo - (void)removeObserver:(id)anObject forKeyPath:(CPString)aKeyPath { - var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self], - index = [_observationProxies indexOfObject:proxy]; + [_observationProxies enumerateObjectsUsingBlock:function(aProxy, idx, stop) + { + if (aProxy._object === self && aProxy._keyPath == aKeyPath && aProxy._observer === anObject) + { + var observedObjects = _observedObjectsByKeyPath[aKeyPath]; - var observedObjects = _observedObjectsByKeyPath[aKeyPath]; - [observedObjects removeObserver:[_observationProxies objectAtIndex:index] forKeyPath:aKeyPath]; + [observedObjects removeObserver:aProxy forKeyPath:aKeyPath]; + [_observationProxies removeObjectAtIndex:idx]; - [_observationProxies removeObjectAtIndex:index]; + _observedObjectsByKeyPath[aKeyPath] = nil; - _observedObjectsByKeyPath[aKeyPath] = nil; + stop(YES); + } + }]; } @end diff --git a/Tests/AppKit/CPKeyValueBindingTest.j b/Tests/AppKit/CPKeyValueBindingTest.j index 2b03ff655..3b9e75ab7 100644 --- a/Tests/AppKit/CPKeyValueBindingTest.j +++ b/Tests/AppKit/CPKeyValueBindingTest.j @@ -315,6 +315,33 @@ [self assert:0 equals:[control objectValueSetterCount] message:@"-setObjectValue should not be called"]; } +- (void)testMultipleBindingsToArrayControllerSelection +{ + var control1 = [[TextField alloc] init]; + var control2 = [[TextField alloc] init]; + + var cheese1 = [BindingTester testerWithCheese:@"roblochon"], + cheese2 = [BindingTester testerWithCheese:@"brie"]; + + var ac = [[CPArrayController alloc] initWithContent:@[cheese1, cheese2]]; + var oc = [[CPObjectController alloc] init]; + +// This tests fails only if multiple controls are binded BEFORE the object controller + [control1 bind:CPValueBinding toObject:oc withKeyPath:@"selection.cheese" options:nil]; + [control2 bind:CPValueBinding toObject:oc withKeyPath:@"selection.cheese" options:nil]; + [oc bind:CPContentBinding toObject:ac withKeyPath:@"selection" options:nil]; + + [ac setSelectionIndex:0]; + + [self assert:@"roblochon" equals:[control1 objectValue] message:@"control1 objectValue is wrong"]; + [self assert:@"roblochon" equals:[control2 objectValue] message:@"control2 objectValue is wrong"]; + + [ac setSelectionIndex:1]; + + [self assert:@"brie" equals:[control1 objectValue] message:@"control1 objectValue is wrong"]; + [self assert:@"brie" equals:[control2 objectValue] message:@"control2 objectValue is wrong"]; +} + @end @implementation TextField : CPTextField