Thanks for the pointers, Quincy. However, I implemented the following accessors, checked I wasn't directly touching m_contents except in my init, and the problem persists.
- (void) setContents:(id)newValue - (NSUInteger)countOfContents - (id)objectInContentsAtIndex:(NSUInteger)idx - (void)insertObject:(id)obj inContentsAtIndex:(NSUInteger)idx - (void)removeObjectFromContentsAtIndex:(NSUInteger)idx I implemented -(BOOL)[Foo respondsToSelector:] to see what else I might be missing, but Foo is only asked about '_finishedMakingConnections' and '_autounbinder'. If I'm still missing an accessor, it must be determined without using respondsToSelector:. On Dec 8, 2011, at 12:34 AM, Quincey Morris wrote: > On Dec 7, 2011, at 20:05 , Eric Slosser wrote: > >> I have an NSTreeController whose 'content array' is bound to another >> object's 'content' key. >> >> It appears that the binding mechanism duplicates the array that was returned >> by [foo content]. >> >> This is bad, because changes that 'foo' makes later to its m_content never >> show up in the window. It's also bad because [NSTreeController >> selectedObject] doesn't correspond to anything in the tree under [foo >> content]. >> >> I can work around this by NOT using bindings to establish the controller's >> content, instead using [NSTreeController setContent:]. >> >> 1. Where in the docs is this binding duplication described? >> 2. Is there a way to use bindings and avoid having [foo content] duplicated? > > Based on this information, the problem is that your Foo class isn't KVO > compliant for the "content" property. > > Conceptually, it's a mistake to think of "content" as an array property (that > is, as a property that has an array as its value). Conceptually, you should > think of it as an indexed to-many relationship. > > The correct approach is to properly implement the KVC indexed collection > accessors in your Foo class**. See: > > > http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/AccessorConventions.html#//apple_ref/doc/uid/20002174-BAJEAIEE > > Normally, you need to write only the 'insert' and 'remove' accessors. You can > let all of the others default. Then, when changing the value of the property, > you should never change m_content directly***. Instead, use the collection > accessors, or use the mutable array proxy. For example, to add an object to > the array, use either of these: > > [foo insertObject: newObject inContentAtIndex: newIndex]; // or … > [[foo mutableArrayValueForKey: @"content"] insertObject: newObject > atIndex]; > > Both of these are KVO compliant, and functionally equivalent. > > Once you have this machinery set up, your binding to Foo's "content" should > work properly. > > > > ** Of course, in practice, the Foo instance has to return *some* object that > looks like an array as the value of the "content" getter, since properties > have types. But think about what object ought to be returned. You don't want > to return your 'm_content' array, because you're exposing an implementation > detail to clients of your Foo class. You don't want to return a copy of your > 'm_content' array, because that of course won't change after being created. > > Catch-22, isn't it? Ideally, the Foo instance would return [self > immutableArrayValueForKey: @"content"] but unfortunately there's no such > method. The simplest choice is probably to return the ivar, but to write no > code that uses the @property value. > > *** When using an array ivar to back an indexed collection property like > this, it's safe to modify the ivar directly in the init method only (because > there aren't any observers at this point). Apart from that method, you should > always use the KVO compliant accessors. > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com