Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUserDefaults and KVO issues

Tags:

ios

I'm using NSUserDefaults in my app and I would like to be notified when a particular value is changed. For that, I added the following lines in viewDidLoad:

NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
[settings synchronize];
[settings addObserver:self forKeyPath:@"pref_server" options:NSKeyValueObservingOptionNew context:NULL];

And the method to be notified:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{

    NSLog(@"Change");

    NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
    if (object == settings && [keyPath isEqualToString:@"pref_server"])
    {
        NSLog(@"Server did change");
    }

}

Unfortunately, the latter is never called...@"pref_server" is the item identifier I have set in Root.plist, in Settings.bundle. What am I doing wrong?

like image 407
J0o0 Avatar asked Apr 19 '11 09:04

J0o0


People also ask

Is NSUserDefaults thread-safe?

Thread SafetyThe UserDefaults class is thread-safe.

What is NSUserDefaults?

A property list, or NSUserDefaults can store any type of object that can be converted to an NSData object. It would require any custom class to implement that capability, but if it does, that can be stored as an NSData. These are the only types that can be stored directly.


3 Answers

Interesting observation:

[NSUserDefaults standardUserDefaults] seems to be KVO compliant now as I am able to observe and bind to it's values. I'm running 10.7.2, using Xcode 4.2, SDK 10.7, LLVM compiler 3.0 .

I can't seem to find this new behavior documented anywhere in the release notes.

like image 67
matt spark Avatar answered Sep 22 '22 19:09

matt spark


I suggest making use of the appropriate notification: NSUserDefaultsDidChangeNotification.

Search for AppPrefs in the Apple Documentation within Xcode and it'll show an example app which does exactly what you want to do. Just compile and run! It makes use of the NSUserDefaultsDidChangeNotification.

This is the code being used to register an observer:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(defaultsChanged:)
                                             name:NSUserDefaultsDidChangeNotification
                                           object:nil];
like image 40
Nick Weaver Avatar answered Sep 26 '22 19:09

Nick Weaver


NSUserDefaults is not KVO compliant, but NSUserDefaultsController is. So you'd use:

NSUserDefaultsController *defaultsc = [NSUserDefaultsController sharedUserDefaultsController];
[defaultsc addObserver:self forKeyPath:@"values.pref_server" 
               options:NSKeyValueObservingOptionNew 
               context:NULL];
like image 21
Mark Lilback Avatar answered Sep 22 '22 19:09

Mark Lilback