• 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: Jim Correia <email@hidden>
  • Date: Mon, 17 Jul 2006 23:37:50 -0400

On Jul 17, 2006, at 9:00 PM, Chris Kane wrote:

The solution is that the context pointer must be used to provide a globally unique value that you can recognize in your class. If you recognize the value, this notification is for you, otherwise you pass the method call up to super and return. You have to use a value that the other classes in the hierarchy won't (or can't) use.

You cannot use NULL as the context pointer, because the superclass (or a subclass) might also use NULL. NULL is a shared value. You can't use selectors, either, because their values are global to the process, and a sub or superclass could potentially use the same one. Plus, recognizing many possible selector values would be a pain and time consuming. It's better to pick one context value.

So one potential solution here is to allocate a dictionary, use that as the context for your class, and also use it as a dispatch table.


Since the dictionary is dynamically allocated using it as the void * context will guarantee uniqueness in the same way as Chris' "ugly" solution in so far as all addresses within the address space are unique. It won't guarantee uniqueness if anyone else uses arbitrary context pointers like this:

static void *ObservationContext = (void *)2091;

The observer would look something like this:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id) object change:(NSDictionary *)change context:(void *)context
{
if (context == dispatchDictionary) {
SEL selector = NSSelectorFromString([dispatchDictionary objectForKey: keyPath]);
// dispatch to self based on the selector looked up in the table
} else {
[super observeValueForKeyPath: keyPath ofObject: object change: change context: context];
}
}


While this solves the problem Matt wanted to solve, there is still a fair bit of ugliness and hand waving going on.

You have to make sure you have one dispatch table per class. You have to keep the dispatch table up to date (as observers are registered). Your class has to know about the dispatch table and correctly implement -observeValueForKeyPath:ofObject:change:context:. It is left as an exercise for the reader to accomplish this correctly, without cut and paste programming.

If I've glossed over something (besides the intentional hand waving), hopefully someone will point it out.

Jim
_______________________________________________
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


References: 
 >Re: KVO and the observeValueForKeyPath bottleneck (From: Matt Neuburg <email@hidden>)
 >Re: KVO and the observeValueForKeyPath bottleneck (From: Chris Kane <email@hidden>)
 >Re: KVO and the observeValueForKeyPath bottleneck (From: Jakob Olesen <email@hidden>)
 >Re: KVO and the observeValueForKeyPath bottleneck (From: Chris Kane <email@hidden>)

  • Prev by Date: Re: Writing application without Interface Builder
  • Next by Date: Re: Data Model Design Q: Translation [Resolved]
  • Previous by thread: Re: KVO and the observeValueForKeyPath bottleneck
  • Next by thread: Re: KVO and the observeValueForKeyPath bottleneck
  • Index(es):
    • Date
    • Thread