2012-05-28 7 views
8

Ho il seguente codice che mira a rilevare l'evento di un valore NSUserDefaults che cambia per una chiave particolare.iOS NSUserDefaults Controllo del cambio di valori per una chiave singola

[[NSUserDefaults standardUserDefaults] addObserver:self 
            forKeyPath:SOME_NSSTRING_VARIABLE 
             options:NSKeyValueObservingOptionNew 
             context:NULL]; 

- (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context 
{NSLog (@"Changed for key %@", keyPath); } 

Ma il observValueForKeyPath non viene mai chiamato. Ho anche provato a sostituire SOME_NSSTRING_VARIABLE con una stringa come indicato in Observing value changes to an NSUserDefaults key ma non ha aiutato.

Aggiornamento: Sto cambiando NSUserDefaults da un tabview. Il codice sopra riportato per monitorare le modifiche si trova in una scheda diversa dello stesso tabviewcontroller. Nella scheda in cui posso monitorare i cambiamenti (la scheda in cui esiste codice di cui sopra), se aggiungo una:

- (void)viewWillAppear:(BOOL)animated 
{ 
[super viewWillAppear:animated]; 
// NSLog(@"viewillappear"); 
NSUserDefaults *FUDefaults = [NSUserDefaults standardUserDefaults]; 
NSLog(@"The username obtained is: %@", [FUDefaults objectForKey:SOME_NSSTRING_VARIABLE]); 
} 

il valore NSUserDefaults aggiornato è ottenuto in modo corretto, ma l'observeValueForKeyPath non è mai stato chiamato.

+0

Si prega di inserire il codice in cui si modifica la variabile anche – trapper

+0

Anche io credo che tu abbia '[[NSUserDefaults st andardUserDefaults] addObserver ... 'all'interno di' viewDidLoad'? – trapper

+0

NSUserDefaults * FDefaults = [NSUserDefaults standardUserDefaults]; [FDefaults setObject: userName.text forKey: SOME_NSSTRING_VARIABLE]; [[NSUserDefaults standardUserDefaults] synchronize]; –

risposta

20

Edit: viewDidUnload ora è deprecato, utilizzare dealloc invece removeObserver

Questo dovrebbe funzionare perfettamente, ho appena testato qui.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[NSUserDefaults standardUserDefaults] addObserver:self 
              forKeyPath:@"SomeKey" 
               options:NSKeyValueObservingOptionNew 
               context:NULL]; 
    // Testing... 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:@"test" forKey:@"SomeKey"]; 
    [defaults synchronize]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 

    [[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:@"SomeKey"]; 
} 

- (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context 
{ 
    if([keyPath isEqual:@"SomeKey"]) 
    { 
     NSLog(@"SomeKey change: %@", change); 
    } 
} 

Cose che è possibile testare.

  • mettere un punto di interruzione nel viewDidUnload e assicurarsi che la vista non sta scomparendo su di voi (dal momento che si sta cambiando SomeKey da un'altra viewController) Se questo è il caso allora forse spostare il registro/de-registrazione codice in init/dealloc a seconda di come funziona il VC.

  • Usa KeyPath esplicito come @"SomeKey" non una sostituzione come SOME_NSSTRING_VARIABLE

+0

Ho appena eseguito un reset completo del telefono (nel simulatore) e ho eseguito anche una pulizia. Ora le cose stanno andando bene. Grazie per il tuo codice Funziona anche con SOME_NSSTRING_VARIABLE –

+1

viewDidUnload è ora deprecato, utilizzare dealloc invece per rimuovereObserver – foOg

+0

Sì, le cose sono cambiate ora – trapper

3

Swift Versione:

func setUserDefaultsListener(){ 
     NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "keyPath", options: NSKeyValueObservingOptions.New, context: nil) 
    } 

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
     if keyPath == "keyPath" { 
      //Do something 
     } 
    } 

    deinit { 
     NSUserDefaults.standardUserDefaults().removeObserver(self, forKeyPath: "keyPath") 
    } 
3

Swift 3 Versione:

override func viewDidLoad() { 
    super.viewDidLoad() 
    UserDefaults.standard.addObserver(self, forKeyPath: "keyPath", options: .new, context: nil) 
} 

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
    if keyPath == "keyPath" { 
     //Do something 
    } 
} 

deinit { 
    UserDefaults.standard.removeObserver(self, forKeyPath: "keyPath") 
} 
Problemi correlati