2012-05-28 9 views
8

Tengo el siguiente código para detectar el evento de un valor de NSUserDefaults que cambia para una clave en particular.iOS NSUserDefaults Viendo el cambio de valores para una sola clave

[[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); } 

Pero observeValueForKeyPath nunca recibe una llamada. Incluso traté de reemplazar SOME_NSSTRING_VARIABLE con una cadena como se menciona en Observing value changes to an NSUserDefaults key pero no me ha ayudado.

Actualización: Estoy cambiando los NSUserDefaults de una pestaña. El código anterior para monitorear los cambios se encuentra en una pestaña diferente del mismo control tabviewcontroller. En la pestaña donde vigilo si los cambios (la pestaña en que existe el código de seguridad), si añado una:

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

el valor actualizado NSUserDefaults se obtiene correctamente, pero el observeValueForKeyPath nunca fue llamado.

+0

Por favor enviar el código en el que cambia el variable también – trapper

+0

También lo tomo tiene '[[NSUserDefaults st andardUserDefaults] addObserver ... 'inside' viewDidLoad'? – trapper

+0

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

Respuesta

20

Editar: viewDidUnload ahora es obsoleto, utilice dealloc lugar a removeObserver

Esto debería funcionar perfectamente, acabo de prueba aquí.

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

Cosas que podrías probar.

  • Deja un punto de ruptura en viewDidUnload y asegúrese de que la vista no está desapareciendo en usted (ya que está cambiando de otro SomeKey viewController) Si este es el caso, entonces mueva el registro/cancelar el registro de código en init/dealloc dependiendo de cómo funciona su VC.

  • Uso KeyPath explícita como @"SomeKey" no es una sustitución como SOME_NSSTRING_VARIABLE

+0

Acabo de hacer un restablecimiento completo del teléfono (en el simulador) e hice una compilación limpia también. Ahora las cosas están funcionando bien. Gracias por tu codigo Funciona incluso con SOME_NSSTRING_VARIABLE –

+1

viewDidUnload ahora está en desuso, use dealloc en su lugar para eliminarObserver – foOg

+0

Sí, las cosas han cambiado ahora – trapper

3

Swift Versión:

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 Versión:

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") 
} 
Cuestiones relacionadas