Re: KVO and the observeValueForKeyPath bottleneck
Re: KVO and the observeValueForKeyPath bottleneck
- Subject: Re: KVO and the observeValueForKeyPath bottleneck
- From: George Orthwein <email@hidden>
- Date: Thu, 20 Jul 2006 15:25:20 -0400
On Jul 18, 2006, at 8:44 PM, Matt Neuburg wrote:
Interestingly, though (or perhaps not, for those who already
realized this),
if what you are planning to do when you get notified thru
observeValue... is
set a corresponding ivar, it might be much simpler to avoid the entire
problem and use bind:... instead of addObserver:... at the outset.
Thanks for this idea, though I actually arrived at my current
observeValueForKeyPath: implementation because I had initially using
bindings! :)
http://www.cocoabuilder.com/archive/message/cocoa/2006/4/17/161225
I already had all the setters there that were called with
bind:toObject:withKeyPath:options: so when I switched to KVO, it
naturally led into trying to call them from my
observeValueForKeyPath: method.
One nice thing is that I can switch back and forth easily just by
swapping out:
[sender bind:@"attributeName" toObject:docPrefsController
withKeyPath:@"selection.attributeName" options:nil];
for
[docPrefsController addObserver:sender
forKeyPath:@"selection.attributeName" options:nil context:NULL];
As you point out, one passes through observeValueForKeyPath: and one
calls the accessors directly.
The main reason I switched away from using bind: was that I found my
setters getting called something like a dozen times when the binding
was first initiated with bind:toObject:withKeyPath:options:. Perhaps
there's a way to coalesce those initial updates. I found it was
bogging down the initial display of the view since it triggered a
dozen or so redraws.
(Ok, I just double checked this and I'm only seeing a single initial
call now when I use bind:! Not sure what I was seeing before because
in my notes I even mention some accessors getting called 24 times! I
probably setup something wrong at some point, though I thought I had
also seen this mentioned in the archives somewhere. More
investigation is in order....)
One thing that tripped me up when I switched to KVO is that
addObserver:forKeyPath:options:context: does NOT send the current
value on initial registration. This means that to sync the view
initially I have to enumerate through the relevant attributes and
call setValue:forKey: manually.
http://www.cocoabuilder.com/archive/message/cocoa/2006/5/20/163920
The point there was that if I say bind:..., I get a "one-way"
binding, which
in effect means that I start observing the thing I'm bound to. In that
thread I was concentrating on the downside, which is that the thing
I'm
bound to does not automatically also start observing me; but now
let's talk
about the upside. The upside is that my ivar gets set automatically
when the
other object's observed attribute changes - without ever passing
through
observeValue...!
So, if what you were going to do was call setValue:forKey: on your
own ivar,
you could skip the whole addObserver: thing and just use bind:,
because
that's exactly what then *will* happen; setValue:forKey: will be
called on
your ivar.
True. I guess if you want to avoid the KVO "bottleneck" you can just
use "one way" bindings instead!
Moreover, in the case of something like an NSController's
"content", this
approach works, when ordinary observing with addObserver: does not.
As has
been pointed out several times recently, the change dictionary
passed to
observeValue... is empty. But if you start with bind:, it works
great; the
new value just gets handed to you directly.
Is this right?. If you bind to "arrangedObjects" the entire array is
sent each time it is modified. I tried binding to "content" and
wasn't getting any updates on modifications so maybe my test was
wrong anyhow. But it doesn't look like you can get just the change/
removed values using bind.
Of course this is officially a misuse of bindings,
I don't think implementing "one way" or "read only" bindings is a
misuse, though it almost seems that way since there aren't any
examples or mentions of it in the docs that I remember seeing. I
think I'll file a doc request.
It does seem to be a sly way of avoiding the observeValueForKeyPath
bottleneck though.
I think I better add a disclaimer since many details of this whole
thing are still fuzzy in my head: Anything stated above may be
completely wrong. There, I feel better. ;)
George
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden