tags:

views:

31

answers:

1

Quite often I encounter a scenario when I want to observe changes on a retained property:

@interface AnObserver {…}
@property(retain) Foo *foo;

Now when I want to set up the observing, I need to write my own setter, repeating all the boilerplate setter code:

- (void) setFoo: (Foo*) newFoo {
    if (newFoo == foo)
        return;
    [foo removeObserver:self forKeyPath:…];
    [foo release], foo = [newFoo retain];
    [foo addObserver:self forKeyPath:…];
}

This is dumb, because it pollutes the source with boilerplate code and it’s easy to miss something. Is there a better way to set up KVO on retained properties? I wish I could write something like Moose’s after hook to change the KVO after the property was changed.

In fact I realized I could watch the property itself:

[self addObserver:self forKeyPath:@"foo"…];

And then change the KVO when the property changes :-), but I do realize this is much more complicated than the hand-written setter I’d like to avoid.

Ideas?

+1  A: 

How about using a key path? Say you want to observe changes on both the value1 and value2 properties of foo. You could use:

[self addObserver:self forKeyPath:@"foo.value1"];
[self addObserver:self forKeyPath:@"foo.value2"];

Then when those properties change, you'll get notifications.

mipadi
This seems to work, thank you!
zoul