• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: bindings duplicates object returned
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bindings duplicates object returned


  • Subject: Re: bindings duplicates object returned
  • From: Eric Slosser <email@hidden>
  • Date: Tue, 13 Dec 2011 12:11:45 -0500

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 (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

  • Follow-Ups:
    • Re: bindings duplicates object returned
      • From: Eric Slosser <email@hidden>
References: 
 >bindings duplicates object returned (From: Eric Slosser <email@hidden>)
 >Re: bindings duplicates object returned (From: Quincey Morris <email@hidden>)

  • Prev by Date: Re: How select NSTextField programatically?
  • Next by Date: Re: Filling gradient in NSTableHeaderView not working properly
  • Previous by thread: Re: bindings duplicates object returned
  • Next by thread: Re: bindings duplicates object returned
  • Index(es):
    • Date
    • Thread