iOS NSUserDefaults监视单个键值的更改

我有下面的代码旨在捕捉NSUserDefaults值为特定键更改的事件。

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

但是,observeValueForKeyPath永远不会被调用。 我甚至尝试用一个stringreplaceSOME_NSSTRING_VARIABLE,正如在观察NSUserDefaults键的值更改中所提到的,但是它没有帮助。

更新:我正在改变TabView的NSUserDefaults。 上述监视更改的代码位于同一个tabviewcontroller的不同选项卡中。 在我监视更改(上面的代码存在的选项卡)的选项卡中,如果我添加一个:

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

已更新的NSUserDefaults值正确获得,但observeValueForKeyPath从未被调用。

编辑: viewDidUnload现在不推荐使用,而是使用dealloc removeObserver

这应该是完美的,我刚刚在这里testing。

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

你可以testing的东西。

  • 在viewDidUnload放置一个断点,并确保视图不会消失在你身上(因为你正在改变另一个viewController的SomeKey)如果是这样的话,那么也许移动你的注册/取消注册代码到init / dealloc根据你的VC工作。

  • @"SomeKey"一样使用显式的KeyPath而不是像SOME_NSSTRING_VARIABLE这样的SOME_NSSTRING_VARIABLE

Swift版本:

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

Swift 3版本:

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