Re: Crash on NSKVOPendingNotificationRelease (KVO, bindings issue?)
Re: Crash on NSKVOPendingNotificationRelease (KVO, bindings issue?)
- Subject: Re: Crash on NSKVOPendingNotificationRelease (KVO, bindings issue?)
- From: Quincey Morris <email@hidden>
- Date: Wed, 21 Apr 2010 20:22:11 -0700
On Apr 21, 2010, at 17:47, Glen Low wrote:
> I'm using KVO as a generalized recalculation engine, somewhat akin to how a spreadsheet recalcuates values based on what's changed. It's mostly successful once you eliminate cycles, but there is a persistent problem.
The likely answer (see below for the reasons) is that this is probably not a good approach. Your application needs a specific behavior of change propagation, cycle elimination -- as well as other possible constraints -- that KVO has no API contract to provide. I'd recommend you spend the effort on designing your own object graph and related behavior.
> On each relevant object, I have a observeValueForKeyPath:ofObject:change:context: method which then triggers willChangeValueForKey: / didChangeValueForKey: for dependent properties. I've noticed that when observeValueForKeyPath:ofObject:change:context gets called more than once in a row for an object, one of the other observed objects dies in didChangeValueForKey: -- here's the stack trace
I *believe* that KVO contains at least one (major? inherent?) bug that causes crashes like this with certain patterns of observations. Whenever I run into such crashes, I've never been able to work out whether it is in fact a bug, or if I did something wrong, nor to recreate the crash in a more controlled context that could be used as the basis of a bug report.
So you might have run into a bug. Or you might have set up an observation pattern that KVO doesn't really support (either at the level of observers or the level of notifications).
KVO has two important defects from the developer's point of view: it's a black box system, so trying to understand what it's doing at any given moment is pure guesswork; and it's an implementation-defined system, so that beyond its general responsibilities, what is does is what it's "supposed to" do, and there's no independent standard of whether it's right or wrong.
Plus, KVO probably doesn't scale well as the number of observations increases. If your object graph is going to get large, performance may well become a consideration.
For all those reasons, I wouldn't suggest using it for an application like this, where *propagation* of the notifications across multiple objects is the key functional issue.
FWIW.
> Side question: I can of course use keyPathsForValuesAffectingValueForKey: and friends to declare the dependencies instead of using a procedure to react to them, but I need to execute code as well e.g. update the observed value. For example, say A = B/C. When either B or C changes, you want A to change too. I can use keyPathsForValuesAffectingA to declare it depends on B or C, but I need to update the cached A value whenever B or C changes -- how would I do that without using observeValueForKeyPath:ofObject:change:context:?
If you really need to "cache" the A value, then you have to use observeValueForKeyPath:ofObject:change:context:. Using keyPathsForValuesAffectingA only makes sense if you're going to produce the A value on demand.
Incidentally, this example points another defect of using KVO for your application. You want A to change when B or C changes, and it will -- literally, meaning twice. Once for the B change, and once for the C change. That means that A may temporarily have an invalid value, and that might itself be propagated via notifications before its final value is calculated. KVO guarantees no order for the notifications, and although in a few cases it might optimize some repeated notifications away you don't have a lot of control over the quantity of notifications that get sent.
_______________________________________________
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