• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: KVO and the observeValueForKeyPath bottleneck
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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
  • Follow-Ups:
    • Re: KVO and the observeValueForKeyPath bottleneck
      • From: Scott Anguish <email@hidden>
References: 
 >Re: KVO and the observeValueForKeyPath bottleneck (From: Matt Neuburg <email@hidden>)

  • Prev by Date: Problems printing an NSScrollView
  • Next by Date: Re: NSBrowserCell not extensible; need sample using NSButtonCell
  • Previous by thread: Re: KVO and the observeValueForKeyPath bottleneck
  • Next by thread: Re: KVO and the observeValueForKeyPath bottleneck
  • Index(es):
    • Date
    • Thread