Re: NSDocument updateChangeCount when using Bindings
Re: NSDocument updateChangeCount when using Bindings
- Subject: Re: NSDocument updateChangeCount when using Bindings
- From: Kevin Bracey <email@hidden>
- Date: Sat, 8 Jan 2011 10:05:08 +1300
Thank you!
As always I had paddled my way out into deep water and missed something important.
Key-Valued Coding Programming Guide: Ensuring KVC Compliance
Ensuring KVC Compliance, Indexed To-Many Relationship Compliance.
Cheers
Kevin
On 7/01/2011, at 7:39 PM, Quincey Morris wrote:
> On Jan 6, 2011, at 18:01, Kevin Bracey wrote:
>
>> MyDocument has a
>> iVar = NSMutableArray *allScenes;
>> @property( retain ) NSMutableArray *allScenes;
>> @synthesize allScenes;
>>
>> In my nib I have a ArrayController bound to allScenes and it is hooked up to a Table and and selected Fields, it is adding and editing my Scene Objects great.
>>
>> I have these Saving and Loading from a Package using NSKeyArchiver, working great.
>>
>> How do I get the [MyDocument updateChangeCount:NSChangeDone]; to be called when I add or delete a allScenes object or edit one of there properties?
>
> You're kinda Doing It Wrong™ and your problem with updating the change count is something of a side effect.
>
> It's almost certainly wrong to expose a *mutable* array ivar as a public *mutable* array property, especially when the the property is synthesized. By doing this, you've allowed clients of your class to modify the property non-KVO-compliantly. (For example, '[document.allScenes addObject:...]' is allowed by your interface but is not compliant.) Currently it "works great", I'm guessing, because currently the *only* way the array gets changed is via the array controller, and the array controller brute-force-ensures KVO compliance on its own accesses. (For example, it adds to the array with something like '[[document mutableArrayValueForKey: @"allScenes"] addObject:...]', which is compliant.) If you later add other ways of changing the array, you're leaving yourself open to a compliance problem, and it's likely to be an extremely hard bug to track down.
>
> The easiest way to fix this is:
>
> 1. Declare the property as '@property (retain) NSArray *allScenes;'.
>
> Counter-intuitively, this won't break your array-controller-initiated updates, since the array controller doesn't know the property type anyway. If you read the comments for 'mutableArrayValueForKey:' in NSKeyValueCoding.h carefully, you'll see that without further intervention KVC will go ahead and update the mutable array anyway (case #3). But that's not what you really want, so also ...
>
> 2. Define mutable array accessors in your document subclass. Something like:
>
> - (void) insertObject: (id) object inAllScenesAtIndex: (NSUInteger) index {
> [allScenes insertObject: object atIndex: index];
> }
>
> and a similar one for removing objects. (Such methods are inherently KVO compliant.) As a result, every object insertion and removal will be done via your custom accessors, and -- magically -- you will now have convenient places to update the document change count.
>
> 3. If code needs to update the array property other than via KVC, you can expose your custom accessors as public methods. As I said, they're inherently KVO compliant, so this solves the original problem in your implementation. Or, clients of the class can use 'mutableArrayValueForKey:' directly. Either way, they'll be forced to do it right, and prevented from doing it wrong.
>
>
_______________________________________________
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