Re: NSArrayController Frustration
Re: NSArrayController Frustration
- Subject: Re: NSArrayController Frustration
- From: Chris Hanson <email@hidden>
- Date: Sun, 25 Nov 2007 20:50:46 -0800
On Nov 24, 2007, at 5:58 PM, David Carlisle wrote:
I am expecting that when I do [docArray addObject:x] that the array
controller will observe the change and do a reloadData on the
NSTableView. That isn't happening.
Your expectation is incorrect. What your NSArrayController is bound
to is not the docArray *object* but the docArray *property* (or key)
of your NSWindowController subclass.
There are a few different ways you can resolve this. You've proposed
one yourself -- to do all manipulations via the NSArrayController --
which I do not recommend because it violates encapsulation and leads
people to mix model and controller level code unnecessarily.
I. Savant suggested that you surround changes to docArray with
{will,did}ChangeValueForKey: pairs to ensure KVO change
notifications. I do not recommend this because it *also* violates
encapsulation -- you're mixing in "maintenance" code with the code
that uses the property. This is fragile in that it will be easy to
forget a spot, post the wrong notification due to a typo, etc.
So, since I've shot down the first two ideas posted, what *do* I
recommend? One of the following:
(1) Make your manipulations of the docArray property specific, by
implementing the appropriate ordered-relationship-KVC accessor methods:
- (NSUInteger)countOfDocArray
- (id)objectInDocArrayAtIndex:(NSUInteger)index;
- (void)insertObject:(id)object inDocArrayAtIndex:(NSUInteger)index;
- (void)removeObjectFromDocArrayAtIndex:(NSUInteger)index;
And so on. The above four are the minimum methods to implement,
beyond -docArray and -setDocArray: -- the full naming pattern is
described in the Key-Value Coding Programming Guide, and it's also
documented in <Foundation/NSKeyValueCoding.h> under -valueForKey: and -
mutableArrayValueForKey:.
Then, instead of manipulating docArray directly, manipulate it only
using the above methods (which are allowed to manipulate the array
directly). Key-Value Observing -- used by bindings -- will
automatically do the right thing and cause the above methods to post
appropriate observer notifications for every manipulation of the
docArray property that occurs via them.
(2) Whether or not you do #1 above, you can just use the
NSMutableArray that you get back from [self
mutableArrayValueForKey:@"docArray"] to manipulate the array. It will
not actually return your own array; instead, it will return a proxy
object that also causes the appropriate KVO notifications to be posted
for every manipulation of your own array. If you *do* do #1 above, it
will even cause the methods you have written to be invoked.
I'm sure this seems complicated -- "I just want to observe an array!"
you're no doubt saying -- but if you remember that observation and
(therefore) binding happens at the property rather than the object
level, it will make a lot more sense. As long as you have the
appropriate methods implemented for the type of property you want to
manipulate, and you manipulate the property through those methods, its
implementation will be irrelevant.
-- Chris
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden