Re: NSArrayController -addObjects and undo - [improved but still confused]
Re: NSArrayController -addObjects and undo - [improved but still confused]
- Subject: Re: NSArrayController -addObjects and undo - [improved but still confused]
- From: "email@hidden" <email@hidden>
- Date: Tue, 10 Nov 2009 22:08:05 +0000
On 10 Nov 2009, at 17:52, Quincey Morris wrote:
> On Nov 10, 2009, at 05:16, email@hidden wrote:
>
>> On 9 Nov 2009, at 20:58, email@hidden wrote:
>>
>>> My Entry objects are an NSManagedObject subclass.
>>>
>>> I create an NSArray of N Entries and add them to my array controller like so.
>>> [self.arrayController addObjects:newEntries];
>>>
>>> I am observing [self.arrayController arrangedObjects] and receive a single observation following the above call.
>>>
>>> However, when I undo this operation I get N observations of [self.arrayController arrangedObjects].
>>>
>> Looking at [[self.arrayController arrangedObjects] count] I can see that the array size is maintained while the observations occur.
>> So it's not as if the added entries are being removed/undone one at a time.
>>
>> I am using KVO on my managed object properties and debugging seems to indicate that these observations are the source of the issue during the undo.
>>
>> So I have found a work around:
>>
>> If I override -didChangeValueForKey: and -didChangeValueForKey: so that notifications are not
>> sent while an undo is in progress then I don't get the unanticipated arrangedObjects observations.
>>
>> Yet I don't understand why I have to do this. Why does undo affect the arrangedObjects in this way?
>>
>>
>>> Is this expected behaviour or am I screwing up on my KVO somewhere?
>>> I have not changed the default undo manager grouping behaviour.
>
> It's not clear there's anything wrong, other than that your expectation of the implementation details doesn't match the reality of them.
Yes, the expectation trap is definitely one of my favourites. It's dark and lonely and you nearly always need someone else to pull you out.
>
> First, you keep saying "observations", but you appear to mean "notifications". Is that correct? Assuming so ...
That is correct.
>
> Second, when an array property is changed, you may get KVO notifications in one of the following patterns:
>
> -- a single notification with the NSKeyValueChangeKindKey set to NSKeyValueChangeSetting, a non-specific notification that the array has changed, but without details of what has changed
>
> -- a single notification with the NSKeyValueChangeInsertion, NSKeyValueChangeRemoval or NSKeyValueChangeReplacement key and an index set given by the NSKeyValueChangeIndexesKey key, specifying which items have changed
>
> -- a series of notifications with any of the NSKeyValueChangeInsertion, NSKeyValueChangeRemoval or NSKeyValueChangeReplacement keys, each detailing part of a complex change
>
> You have no direct control over which pattern of notifications you get -- it depends on several factors in the implementation of the object that is changing and the object that is changing it. In particular, you may get a series of notifications (say, of insertions) when it seems that it *could* have been a single notification. Also, the notification that happened before undoing is unrelated (from a KVO point of view) to the notifications generated by undo, so you may get a different pattern in each scenario.
>
I accept all of this except that when observing NSArrayController -arrangedObjects it seems that NSKeyValueChangeSetting is all you ever get, regardless of the nature of the changes to the underlying content.
Presumably this is because arrangedObjects is derived from the content as a result of sorting and predicate filtering.
I comprehend that from a KVO point of view there is no reason why the do/undo notifications should be symmetrical.
But from an NSUndoManager perspective it would seem like a rational expectation that is not met in practice.
Perhaps if I was working with the content object directly this issue would not arise but I cannot see me moving away from -arrangedObjects.
> Your code is going to have to be able to handle all the notification patterns. Typically, this just means processing each notification as it arrives. If this causes a performance or other problem, you will probably need to invent a strategy to defer or coalesce notifications until the end of the undo operation. Overriding will/didChangeValueForKey: is a lousy idea in general.
I agree that overriding will/didChangeValueForKey is counter productive.
My so called work around kills KVO notifications for simple property changes - so it's a non starter.
Coalescing the KVO notifications and deferring action until the end of the undo operation looks like the way to go.
I already used coalesced NSNotifications elsewhere so it's a similar principle applied in a more restricted circumstance.
Thanks for the reply.
>
>
> _______________________________________________
>
> 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
_______________________________________________
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