This post describes how to use KVC to bind the contents of a mutable array into an NSArrayController so that adding and removing elements from the underlying array will trigger corresponding behaviour in the array controller.

Basic Setup

For the purpose of this article, I’m going to use a straw-man class called BDHouse that has a property called rooms that will, surprisingly, contain BDRoom objects. For simplicity’s sake, each room will have a single property called name.

With these basic classes, you have enough to bind the contentArray of your NSArrayController to the rooms property of the house. The array controller can then be bound to an NSTableView or whatever UI control you are using and the UI will display the contents of your array. However, there are a few scenarios where the UI won’t display changes to your rooms.

What does work

Firstly, adding and removing rooms via the Array Controller‘s addObject: or removeObject: methods will work fine. The array controller will update the underlying model and also ensure the UI reflects the new state.

Secondly, if you replace the entirerooms value by doing something like:

What does NOT work

Adding/removing rooms by manipulating the mutable array directly. For example:

BDRoom *room = ...;
[house.rooms addObject:room];

This will add the room to the array, however, the array controller currently has no visibility of the changes. Fixing this problem is the point of this article.

KVC Compliance

You might be tempted to think that the array controller should be aware of the changes made to the rooms property. The reason it does not though is that the house object is not fully KVC-compliant for the rooms key.

But, I hear you exclaim, we’ve declared rooms as a property… surely it is already KVC compliant? The thing is that a property itself can’t be KVC compliant; rather, a class is (or is not) KVC-compliant for a particular property.

So, how do we make BDHouse KVC-compliant for the rooms key? Apple does a pretty good job of explaining it in their KVC Programming Guide, however I think, generally speaking, that the biggest problem here is that the linkage between NSArrayController and its expectation of KVC compliance is quite subtle and non-discoverable.