Previous Entry Add to Memories Tell a Friend Next Entry
NSArrayController design patterns
userpic
[info]chanson
So in building an application that uses NSArrayController, I stumbled across the same issue that a number of Cocoa developers have.

The issue is that, in many cases, you want to programmatically manipulate the contents of the array an NSArrayController is bound to. For things like master-detail interfaces, NSArrayController will do everything for you including manage the array, but for other things — like, say, buddy lists — you'll want to manipulate the array directly and have the changes reflected in your interface.

The problem is that NSMutableArray doesn't actually broadcast Key-Value Observing notifications. I call this a bug, but it's not clear whether or not it'll be fixed. So you can't write code like [buddies addObject:buddy]; and expect a table managed by an NSArrayController to be updated.

Thanks to mmalcolm crawford's notes on the controller layer, I figured out what needs to be done. Essentially, you can either use Key-Value Coding within your class to manipulate your array, or you can use the Key-Value Coding compliant accessor methods to manipulate your array's contents. In other words, you can either do
[[self mutableArrayValueForKey:@"buddies"] addObject:buddy]
or you can do
[self insertObject:buddy inBuddiesAtIndex:[self countOfBuddies]]
assuming you implement -insertObject:inBuddiesAtIndex: and -countOfBuddies.

The thing that tripped me up was that KVC compliant accessor methods are not the same as Scripting KVC compliant accessor methods. So don't go looking at the documentation for NSScriptKeyValueCoding as a guide for what to implement to generate KVO notifications. Hopefully another thing that will be considered a bug...

(Leave a comment)

Typo in method names

(Anonymous)

2008-11-28 07:49 am (UTC)

You have used "into" in your indexed accessor name, where there should only be "in".

The method should be -insertObject:inBuddiesAtIndex:.

Re: Typo in method names

[info]chanson

2008-11-29 05:44 am (UTC)

Thanks for the catch! I'll update the page.

NSArrayController KVO

(Anonymous)

2009-02-26 09:46 pm (UTC)

Hi Chris,
I realize that this was written a while ago, but found it while searching for something else.

It has been my experience with NSArrayController and it's bindings is that you can add and remove objects to the arrays that it is bound to by using the controllers add/removeObject(s): methods. This is manipulate your array as well.

Re: NSArrayController KVO

[info]chanson

2009-02-26 11:57 pm (UTC)

Don't do that unless you're doing it at the view/controller level. At the model level, you should always manipulate to-many relationships using the to-many relationship accessors that I point out above. You should not be using NSArrayController methods from model-level code, and using them from controller-level code is dubious.

They're a convenience for simple action methods. They're not the way to manipulate relationships.

(Leave a comment)