But occasionally I've need to have my code do something when the preference value changes and Key-Value observing seemed like the obvious way to make this work. Unfortunately I didn't know the right incantations and I'd end up needing to add an action method that was triggered when the user interacted with the control. It worked, but it seemed like I was mixing metaphors and there should be a nicer way to deal with this situation.
It turns out that there is a nice way to live wholly in a bindings world. NSUserDefaultsController provides -sharedUserDefaultsController which returns the right controller to add the observer to. Good so far.
But there is one further little wrinkle to make this work. While you might think that the keyPath you are observing would be the usual key string used to reference the preference, but that isn't right. You need to prefix your key with "values.".
Putting these two pieces of the puzzle together gives you code that looks something like the following:
// use this in your init routine
[[NSUserDefaultsController sharedUserDefaultsController] addObserver: self
forKeyPath: @"values.MyPreferenceKey"
options: 0
context: NULL];
along with implementing this method:
// implement this method to handle the notifications
- (void) observeValueForKeyPath: (NSString *) keyPath
ofObject: (id) object
change: (NSDictionary *) change
context: (void *) context
{
if ([keyPath isEqualToString:@"values.MyPreferenceKey"]) {
// do something in response to that change
}
}
and of course, don't forget to remove this later:
- (void) dealloc
{
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver: self
forKeyPath: @"values.MyPreferenceKey"];
[super dealloc];
}
No comments:
Post a Comment