Re: KVO and lazy loading
Re: KVO and lazy loading
- Subject: Re: KVO and lazy loading
- From: Ron Lue-Sang <email@hidden>
- Date: Wed, 22 Oct 2008 22:42:50 -0700
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.
--------------------------
RONZILLA
_______________________________________________
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