I've done some simple KVO setups. Now I have a bit more complex one. I have a singleton object that is settable. That is reachable with code like
[Site singleton].value
I can (and have) watch that singleton
for changes in it's value
property. But I would also like to watch a property of the current value (IF it's not nil). It has a valves
property that I would like to notice changes in.
Without knowing any better, I guess I can do something like
value
property like I'm used tovalves
property as well IF it is non nilvalves
watching it was doing on the previous value
.This seems... burdensome.
I see that you can do more complex keyPath
s but I've not found documentation that explains how to use them. Are they something that could make this problem easier? If not, is this a pattern that others have found a good solution for?
I can provide a better answer if I know a little more about the code involved, but this should be easy. I will assume that the observer is a view controller, but this is the most straightforward way of setting this up.
- (void)viewWillAppear:(BOOL)animated
{
// …
[[Site singleton] addObserver:self forKeyPath:@"value" options:0 context:NULL];
[[Site singleton] addObserver:self forKeyPath:@"value.valves" options:0 context:NULL];
}
- (void)viewWillDisappear:(BOOL)animated
{
// …
[[Site singleton] removeObserver:self forKeyPath:@"value"];
[[Site singleton] removeObserver:self forKeyPath:@"value.valves"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:@"value"]) {
// …
} else if ([keyPath isEqualToString:@"value.valves"]) {
// …
}
}
See Key-Value Coding Fundamentals.
Observe something that you know the full lifecycle of. A singleton is a good choice as long as it truly lives the whole life of the application. Generally, I stick to objects observing themselves.
Add an observer right when you need to do observing, remove an observer as soon as you no longer need observing. Always adding an observer in -init*
and removing it in -dealloc
is asking for trouble.