Re: Core Data faulting and bindings: recursive KVO notifications?
Re: Core Data faulting and bindings: recursive KVO notifications?
- Subject: Re: Core Data faulting and bindings: recursive KVO notifications?
- From: Dennis Lorson <email@hidden>
- Date: Sat, 29 Mar 2008 13:30:33 +0100
On 29 Mar 2008, at 06:08, Ben Trumbull wrote:
On Mar 28, 2008, at 7:38 PM, Dennis Lorson wrote:
On 28 Mar 2008, at 20:24, Ben Trumbull wrote:
The problem I'm having arises when selecting all images at once
(Command+A), if they are fairly large in number (in my store:
~2000).
This takes an enormous time that is definitely > O(n).
Command-A should be instantaneous, even for selections 10x larger.
The typical performance problems I've seen with array controller
selections are (1) complex KVO observer actions cascade (2)
tripping faults unnecessarily (3) using expensive array controller
options.
(1) Complex KVO observer actions need to be carefully constrained.
If they simply grow organically, then it's pretty easy to fall
into the trap of observers creating side effects that trigger
other observers that cascade to yet more observers. This (a)
makes your code impossible to understand, since no one ever
intentionally designed their app that way from the beginning, and
(b) sucks for performance.
This seems like an easy mistake indeed. However, I checked my code
for this when originally debugging the issue, and while it is
difficult to eliminate all cases, no custom KVO observer triggers
other observers as for my subclass implementation -- and if they
do, they relate to disjunct entity objects that should not trigger
others.
You've bound the text fields to the selection poorly. That's the
easiest and best fix. Other workarounds for your edification below.
Well, it might be far from ideal for CD performance, but that doesn't
mean it's bound poorly. It is done exactly to do what we need it to
do, otherwise this binding would have been the first to be targeted
for rewrite.
I really do require the app to be able to show the user the values of
about 1000 items at once, e.g. for a stack of related items. If they
are the same for every item, it is important that that value be
visible to the user.
And this is one thing Bindings as it is, cannot do properly: The
creation of all observation info (one dictionary for each bound
property of each item in the selection) when selecting is just too
much overhead. Plus you easily encounter the aforementioned stack
overflow.
The good news is that the issue is entirely avoidable by batch
faulting using the 10.5 [NSFetchRequest
setReturnsObjectsAsFaults:NO] and executing the fetch on all
objects in the selection.
Yes. You can also do something like this to ignore KVO
notifications around faulting:
<code>
OK, I'll try this.
But still, I have two questions:
- Am I overlooking something obvious? If it is the correct
approach, someone else must have experienced this in a larger
master-detail set, right?
Yes, you should disable "Allows Editing Multiple Values Selection"
when you expect selection to include more than a handful of objects.
This is as said a compromise I cannot make...
Properties should be propagatable to 1000 objects at once for my
users, as they work equally with individual images and up till 1000-
image stacks. I guess this calls for an extra layer of indirection,
with a real separate entity representing the image stack and
propagating the changes, without having 1000s of observers-observed
object relationships.
If it's actually recursing through the entire graph, then it's
probably a bug in your observer method. If it's looping, then it
could simply be toggling off a few array controller options will
address the issue.
You should file a bug with bugreport.apple.com, and include the
entire stack trace. Without the rest of it, it's hard for me to
say if this is the expected stack depth or not. It may be a
problem with one of your custom observation methods not coexisting
happily with faulting, but it's a bit hard to tell from this
excerpt.
As you can verify from the test project, I don't use any custom KVO
logic. Still, the crash should occur almost every time, after a
variable amount of time (seconds range).
Yes, thanks. Sample projects are terrific. So this project suffers
from both the KVO faulting issue, and a poorly bound text field.
Binding to .selection.a is going to call -valueForKeyPath:@"a" on
the array that's selected, which is 10,000 objects. Since the text
field can only show one of those values, this is kinda pointless.
This is the source of the recursion. Selection is based on the
entire array, which doesn't play well with KVO notifications during
faulting.
I understand what happens, but fetching those 10.000 values is exactly
I expect and need to happen, because there is a real chance that they
are the same, and then "Multiple Values" is very confusing to the user.
The fetching itself can actually be very fast with CD, be it not
completely instantaneous. It was just the recursive fetching that
ruined things, so your batch faulting tip was very helpful.
If you go into the Text Field's binding (cmd-4) and disable "Allows
Editing Multiple Values Selection" then the detail fields go blank
with multiple selections, but work as expected with a single
selection.
I would have to be able to customize this Multiple Values behavior,
depending on the precise objects that are selected. When stack-
related images are selected, this behavior may not be used. I'll try
that by overriding some KVO methods in the array controller.
Dennis
_______________________________________________
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