Customising NSArrayController arranged object removal

NSArrayController is quite possibly one of the most useful classes in Cocoa; it applies to so much situations in a modern application. Quite often you may need to subclass it to customise some aspect of the behaviour.

In particular, overriding -insertObject:atArrangedObjectIndex: is particularly handy. I use it regularly with Core Data so that inserting a managed object updates some kind of index attribute for sorting objects by. The documentation is on your side here, calling out the reason to override this method.

But what if you need to customise the behaviour when removing objects too? In the example above you could use it to update the index attribute of any remaining objects. Or your controller might be managing some unusual kind of relationship where removing an object requires extra work such as deleting unused objects.

If so, the docs are no longer on your side. No indication is given how you might do this – although there is a helpful note about the behaviour of -removeObject: with Core Data. Unsatisfied (yes, I filed rdar://7447617), I was forced to seek the answer by trial and error. So without further ado, here's the solution. Some simple drop-in code for your own custom classes:


@implementation MYArrayController
- (void)willRemoveObject:(id)object;
{
    // Put your removal handling code here
}
- (void)removeObjects:(NSArray *)objects
{
    // -removeObject: calls this method internally.
    // Iterate the objects, reporting each one
    for (id anObject in objects)
    {
        [self willRemoveObject:anObject];
    }
    [super removeObjects:objects];
}
- (void)removeObjectAtArrangedObjectIndex:(NSUInteger)index
{
    // -removeObjectsAtArrangedObjectIndexes: calls this repeatedly
    id object = [[self arrangedObjects] objectAtIndex:index];
    [self willRemoveObject:object];
    [super removeObjectAtArrangedObjectIndex:index];
}
@end

© Mike Abdullah 2007-2009