On Oct 23, 2008, at 12:42 AM, Ron Lue-Sang wrote:

Hey Ashley,

On Oct 21, 2008, at 12:23 AM, Ashley Clark wrote:

I'm pretty sure I've got this worked out and it seems to be working, BUT I thought that before and when I turned on Auto Arrange Content on my NSArrayController's this bug popped up. So I wanted to make sure I'm doing this right.


I'm lazily initializing objects that are being read from a database, similar to CoreData faulting. In my RMDatabaseObject class I've implemented a willAccessValueForKey: method that reads in data from the database if necessary. This method is being called at the beginning of my willChangeValueForKey: and willChangeValueForKey:withSetMutation:usingObjects: methods.

Originally, for every property that was being set through the willAccessValue method I was calling the willChange/didChange methods and it seemed to work well. At least until I turned on auto- arrange content on some array controllers. After that I started getting exceptions stating that observer's were being removed more times than they had been added on seemingly random key paths.

I finally found a comment by mmalc and seconded by Ronzilla at http://theocacao.com/comment/4423 that seems to indicate that one should NEVER post change notifications when doing this sort of lazy-loading.

 1) Don't send the KVO notification from inside an accessor.
2) Don't change what the result of the accessor would be without sending a KVO notification.

I guess thing 2 sounds like it contradicts thing 1, but it really doesn't.

If the object were uninitialized, the return value would be some uninitialized value. You never return an uninitialized value tho, so you're not violating 2 by adhering to 1 for the kinda-special case of lazy accessors.

I guess I'm only seconding my own statement, with an attempt at explaining it differently.

Here's one: implementing MyObject's foo to return [[self someToManyRelationshipCollection] objectAtIndex:randomInteger] and then observing myObject.foo.property would be bad. The result of foo changes every time you ask for it. From what I remember in my electrical engineering days, this is one of those hand-waving things we used to do when doing calculations. "We don't care what the values were before time t0. We're only interested in the value from time t0 onward."

Here, we don't care what the value backing the foo accessor was before we started observing foo. But, we'll want to know what the value of foo is as soon as we start observing foo - so you don't need to say you changed foo. For KVO, we wouldn't know what foo changed from until after the initial access of foo which we're talking about. After that we'll track new values as time goes by using will/did change and all will be Good™.

Let me know if I'm still not being clear. Or if I'm answering the wrong question.

No, that makes perfect sense to me. And after reading the comment at theocacao it all just kind of clicked that, duh, obviously I don't need to send notifications that things are being set since from the perspective of any other class, they could have been set from the very start. I was just being overly cautious by wrapping every thing via willChange/didChange when in this instance it turns out I shouldn't have been.

Anyway, mostly I just wanted to make sure that I was interpreting the comments correctly. Since I've changed my code to not issue notifications in this case KVO seems to be working happily 100% of the time!

Ashley

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to