Re: KVO and the observeValueForKeyPath bottleneck
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