diff --git a/AppKit/CPObjectController.j b/AppKit/CPObjectController.j index 82589d689..4905413e8 100644 --- a/AppKit/CPObjectController.j +++ b/AppKit/CPObjectController.j @@ -579,6 +579,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo - (void)removeObjectAtIndex:(unsigned)anIndex { + var currentObject = [self objectAtIndex:anIndex]; + for (var i = 0, count = [_observationProxies count]; i < count; i++) { var proxy = [_observationProxies objectAtIndex:i], @@ -588,7 +590,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo if (operator) [self willChangeValueForKey:keyPath]; - [anObject removeObserver:proxy forKeyPath:keyPath]; + [currentObject removeObserver:proxy forKeyPath:keyPath]; if (operator) [self didChangeValueForKey:keyPath]; @@ -777,8 +779,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo [proxy setNotifyObject:YES]; [_observationProxies addObject:proxy]; - // We keep are reference to the observed objects - // because the removeObserver: will be called after the selection changes + // We keep a reference to the observed objects because removeObserver: will be called after the selection changes. var observedObjects = [_controller selectedObjects]; _observedObjectsByKeyPath[aKeyPath] = observedObjects; [observedObjects addObserver:proxy forKeyPath:aKeyPath options:options context:context]; diff --git a/Tests/AppKit/CPArrayControllerTest.j b/Tests/AppKit/CPArrayControllerTest.j index 1b676222c..08597ab64 100644 --- a/Tests/AppKit/CPArrayControllerTest.j +++ b/Tests/AppKit/CPArrayControllerTest.j @@ -8,6 +8,7 @@ CPArray _contentArray @accessors(property=contentArray); CPArray observations; + int aCount @accessors; } - (CPArray)makeTestArray @@ -289,6 +290,40 @@ [self assertFalse:[[arrayController arrangedObjects] containsObject:objectToRemove] message:@"removed objects should no longer appear in arrangedObjects"]; } +- (void)testRemove_ +{ + var arrayController = [self arrayController], + objectToRemove = [[arrayController arrangedObjects] objectAtIndex:0]; + + [arrayController setSelectedObjects:[objectToRemove]]; + [arrayController remove:nil]; + + [self assertFalse:[[arrayController arrangedObjects] containsObject:objectToRemove] message:@"removed objects should no longer appear in arrangedObjects"]; +} + +- (void)testRemoveObjectsAtArrangedObjectIndexes_ +{ + var arrayController = [self arrayController]; + + [arrayController removeObjectsAtArrangedObjectIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(1, 2)]]; + + [self assert:1 equals:[[arrayController arrangedObjects] count] message:@"objects should be removed"]; +} + +- (void)testRemoveObjectsAtArrangedObjectIndexes_whenObservingCount +{ + var arrayController = [self arrayController]; + + [arrayController addObserver:self forKeyPath:@"arrangedObjects.name" options:0 context:nil]; + [self bind:@"aCount" toObject:arrayController withKeyPath:@"arrangedObjects.@count" options:nil]; + + // This crashed in a previous version of Cappuccino due to an error in _CPObservableArray's removeObjectAtIndex. + [arrayController removeObjectsAtArrangedObjectIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(1, 2)]]; + + [self assert:1 equals:[[arrayController arrangedObjects] count] message:@"objects should be removed"]; + [self assert:aCount equals:[[arrayController arrangedObjects] count] message:@"count should be updated"]; +} + - (void)testSelectionWhenObjectsDisappear { // If the selected object disappears during a rearrange, the selection