Quarter Life Crisis

The world according to Sven-S. Porst

« Mysterious SkinMainWrecked »

Key Value Observation

453 words

Who knows about a good place to read about key-value stuff and bindings in Cocoa? And most notably debugging those?

More precisely: I played around with persistent stores and bindings in Cocoa a bit (what can I say, my relationship with bindings always contains a good dash of hate just because editing more than one or two of them in Interface Builder is a real pain due to the clumsy UI for that) and I ended up wanting to do key value observation to keep track on the value of some variable (essentially it’s a string which could be an AppleScript and I’d like to instantly compile it, so I want to be notified when my string variable changes which in turn seems to be just what key value observation is for).

So I signed up to be notified of changes to that variable (which actually lives in a managed object context in case that matters) and I get notifications. The problem is that I keep getting loads of them, and I completely don’t understand why. In particular I keep getting a notification of the same change over and over (and over…) again and I can’t figure out where it comes from. Looking around the debugger even suggests that further up in the call tree is actually my own class but just when it retrieves a different value from the same object.

Essentially my call stack looks like this in the situation:

Call stack from the debugger

I get called for the variable change I registered for. And a number of steps before my own class is in there as well. So I had a look which line this was at and that line only reads:

if ([[myMO  valueForKey:@"xUpperLevel"] floatValue] < x) { 
i.e. all I do in that line is retrieve a value for a key (and not even the key I am observing). So how does this trigger me being called for observing the value of that other key? Is just the display of the active line wrong? Or is my understanding of things wrong? (Entirely possible, my experience with these ‘newer’ Cocoa techniques is quite small).

Currently this happens in what looks like the ‘setup’ phase of creating the document. So the change I am observing is that of an empty value for the string being replaced by the default value as specified in my data model. (BTW, what’s the ‘proper’ way to determine the point in time when the managed object context has been fully set up? When trying to access it early on, and not really early on, I frequently found that the managed object context didn’t contain any objects.)

Any solution or hint how to figure out what’s actually going on there is very welcome.

September 21, 2006, 0:23

Comments

Comment by Dan W.: User icon

Welcome to our world!

(Not to be flippant … it’s just that this is just the kind of thing that has had us tearing out hair out for over a year….)

September 21, 2006, 2:46

Comment by ssp: User icon

Thanks for the warm welcome Dan…

Does that sound as if there still aren’t any helpful sources on these topics and that I’m pretty much on my own with this? I had hoped that there might be some hidden source of collected wisdom derived from the suffering of the early adopters… after all I just wanted to indulge in a little fun project.

September 21, 2006, 10:57

Comment by Matthias Wilm: User icon

My guess is that even though NSManagedObjects and NSManagedObjectContexts propose to use key-value observation a lot it is actually difficult to do.

In my understanding: the reason for this is that the livetime of an NSManagedObject is (close to) entirely managed by the NSManagedObjectContext. So - if you write: [[myMO valueForKey:@”xUpperLevel”] floatValue] you “wake up” (instantiate) the entire myMO object - all its properties go through initialization.

If you have a awakeFromFetch method this will be executed. This might cause changes to the observed property.

Still worse is that you can not control when the object is faulted. Key-Value observation is not retaining the objects. If you release an ordinary object you have to make sure that key-value observations are unbound. How to do this if you have only a method like: didTurnIntoFault (and not willTurnIntoFault) ?

The consequence I see is that a NSManagedObject should not be an observer. You could make the NSManagedObjectContext an observer of a property of its NSManagedObjects - but then you have to subclass it. Or like NSArrayController you create a controller object (inheriting from NSObject directly) for the managed object that is the observer.

Kindly Matthias Wilm

December 7, 2006, 12:23

Comment by ssp: User icon

Thanks for the info Matthias. While I dumped CoreData from my simple project which doesn’t really need all the bells and whistles of that technology, I’ll try to keep this in mind, in case I’ll work with CoreData for real one day.

December 7, 2006, 16:03

Add your comment

« Mysterious SkinMainWrecked »

Comments on

Photos

Categories

Me

This page

Out & About

pinboard Links

♪♬♪

Received data seems to be invalid. The wanted file does probably not exist or the guys at last.fm changed something.

People

Ego-Linking