Skip navigation.
 
mlRe: KVO and the observeValueForKeyPath bottleneck
FROM : Jakob Olesen
DATE : Mon Jul 17 23:16:19 2006

On 17/07/2006, at 18.09, Chris Kane wrote:

> I'm just curious ... with the trivial approach above, and the other 
> ones involving the context being a keypath and so on ...  has 
> anyone considered what will happen if a superclass or subclass (of 
> whatever class that is) is also doing KVO (on either same or 
> different keys) of the same objects?


Well, not until you brought it up.

If you are subclassing a foreign class without documented behavior, 
the context pointer is useless. Basically you don't know if the 
superclass is already observing an object, so the context pointer 
could be mine or the superclass', who knows?

Further, if you are expecting to be subclassed, you must document 
exactly which objects and key paths you are observing, otherwise the 
subclass can accidentally overwrite your context pointer. (What 
happens if you call addObserver twice on the same object/key path?)

Quick test: you get two callbacks, calling removeObserver removes 
them one at a time, last in first out. (linked list?)
Calling addObserver twice with identical arguments (incl. context) 
also gives you two callbacks.

So, if you don't trust your subclasses and superclasses, you are 
given a void pointer that you may or may not have created yourself. 
That is very close to useless.

This is what I would do, if I was writing class intended for 
subclassing: Use

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)
object change:(NSDictionary *)change context:(void *)context
{
    [self performSelector:(SEL)context withObject:[NSNotification 
notificationWithName:keyPath object:object userInfo:change]];
}

and tell subclasses that they can depend on it being so. Tell 
subclasses to not call super with a context pointer that is not a 
valid selector. Know that one change may cause multiple callbacks.

When writing a subclass: Ignore context completely, dispatch on 
keyPath and/or object


Alternative solution: Create your own, private helper object and 
register that instead.

@interface KVOHelper {
    id owner;
}
@end

@implementation KVOHelper
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)
object change:(NSDictionary *)change context:(void *)context
{
    [owner performSelector:(SEL)context withObject:[NSNotification 
notificationWithName:keyPath object:object userInfo:change]];
}
@end

Don't tell anyone about that object, and you'll be fine.

The KVO API expects observers to have a single personality, so that 
is probably the way to go if you are in the middle of a class hierarchy.

Related mailsAuthorDate
mlKVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 14, 19:44
mlRe: KVO and the observeValueForKeyPath bottleneck George Orthwein Jul 15, 07:36
mlRe: KVO and the observeValueForKeyPath bottleneck Aaron Burghardt Jul 15, 22:56
mlRe: KVO and the observeValueForKeyPath bottleneck Jakob Olesen Jul 17, 12:38
mlRe: KVO and the observeValueForKeyPath bottleneck Jakob Olesen Jul 17, 13:03
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 17, 16:38
mlRe: KVO and the observeValueForKeyPath bottleneck Jakob Olesen Jul 17, 16:57
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 17, 17:31
mlRe: KVO and the observeValueForKeyPath bottleneck Chris Kane Jul 17, 18:09
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 17, 19:49
mlRe: Re: KVO and the observeValueForKeyPath bottleneck Michael Ash Jul 17, 20:11
mlRe: KVO and the observeValueForKeyPath bottleneck Chris Kane Jul 17, 20:24
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 17, 20:31
mlRe: KVO and the observeValueForKeyPath bottleneck Scott Anguish Jul 17, 22:00
mlRe: KVO and the observeValueForKeyPath bottleneck Chris Kane Jul 17, 22:42
mlRe: KVO and the observeValueForKeyPath bottleneck Jakob Olesen Jul 17, 23:16
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 18, 00:43
mlRe: KVO and the observeValueForKeyPath bottleneck Chris Kane Jul 18, 03:00
mlRe: KVO and the observeValueForKeyPath bottleneck Jim Correia Jul 18, 05:37
mlRe: KVO and the observeValueForKeyPath bottleneck Jakob Olesen Jul 18, 16:06
mlRe: KVO and the observeValueForKeyPath bottleneck Jim Correia Jul 18, 18:11
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 19, 02:44
mlRe: KVO and the observeValueForKeyPath bottleneck George Orthwein Jul 20, 21:25
mlRe: KVO and the observeValueForKeyPath bottleneck Scott Anguish Jul 20, 22:14
mlRe: KVO and the observeValueForKeyPath bottleneck Matt Neuburg Jul 21, 03:57
mlRe: KVO and the observeValueForKeyPath bottleneck Scott Anguish Jul 21, 10:11
mlRe: KVO and the observeValueForKeyPath bottleneck George Orthwein Jul 21, 17:46
mlRe: KVO and the observeValueForKeyPath bottleneck Scott Anguish Jul 21, 23:01