2011-04-19 10 views
6

Używam NSUserDefaults w mojej aplikacji i chcę otrzymywać powiadomienia o zmianie konkretnej wartości. Do tego dodałem następujące linie w viewDidLoad:Problemy NSUserDefaults i KVO

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

i metoda być zgłoszone:

- (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"); 
    } 

} 

Niestety, ten ostatni nigdy nie jest nazywany ... @ „pref_server” jest identyfikatorem pozycja Ustawiłem w Root.plist, w Settings.bundle. Co ja robię źle?

Odpowiedz

16

Proponuję skorzystać z odpowiedniego powiadomienia: NSUserDefaultsDidChangeNotification.

Wyszukaj AppPrefs w dokumentacji Apple w XCode, a zobaczysz przykładową aplikację, która robi dokładnie to, co chcesz zrobić. Po prostu skompiluj i uruchom! Korzysta z NSUserDefaultsDidChangeNotification.

Jest to kod używany do rejestracji obserwatora:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(defaultsChanged:) 
              name:NSUserDefaultsDidChangeNotification 
              object:nil]; 
+0

Dziękuję bardzo, że teraz działa jak czar :) – J0o0

+0

Dla Swift3: 'NotificationCenter.default.addObserver (self, \t selektor: #selector (defaultsChanged) \t nazwa: UserDefaults.didChangeNotification, \t object: nil) ' – Yohst

2

NSUserDefaults nie jest zgodny z KVO, ale NSUserDefaultsController jest. Więc chcesz użyć:

NSUserDefaultsController *defaultsc = [NSUserDefaultsController sharedUserDefaultsController]; 
[defaultsc addObserver:self forKeyPath:@"values.pref_server" 
       options:NSKeyValueObservingOptionNew 
       context:NULL]; 
+12

NSUserDefaultsController nie jest dostępny w Cocoa Touch na iOS. –

5

Ciekawe spostrzeżenie:

[NSUserDefaults standardUserDefaults] wydaje się być zgodny KVO teraz jak jestem w stanie obserwować i wiążą się z jego wartości. Używam wersji 10.7.2, używając Xcode 4.2, SDK 10.7, LLVM compiler 3. 0.

Nie mogę znaleźć tego nowego zachowania udokumentowanego w dowolnym miejscu w informacji o wersji.

+1

Założę się, że to nieudokumentowana zmiana w Lwie. W notatkach do wydania wspomniano o pewnych zmianach pod maską ustawionych domyślnie, więc domyślam się, że wsparcie KVO zostało zmienione w tym samym czasie. Konieczność użycia kontrolera dla KVC/KVO jest udokumentowana w tematach programowania powiązań z kakao dla Snow Leopard i Lion. –

+0

To również działa pod OS X 10.8 Mountain Lion. –

+3

Pytanie dotyczyło konkretnie [tag: ios]. –

2

Chociaż nie jest dobrze udokumentowany, NSUserDefaults obsługują obserwacje w parach klucz-wartość w iOS7.

+0

Wygląda na to, że nie działa na iOS9 – jeeeyul