2012-05-28 7 views
8

特定のキーに対してNSUserDefaults値が変化するイベントをキャッチするために、次のコードを用意しました。iOS 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が呼び出されることはありません。私もObserving value changes to an NSUserDefaults keyに記載されているように、SOME_NSSTRING_VARIABLEも文字列で置き換えようとしましたが、それは助けになりませんでした。

更新: 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が呼ばれることはなかったです。

+0

変更コードを投稿してください変数もtoo – trapper

+0

また、私はそれを取る '[[NSUserDefaults st andardUserDefaults] addObserver ... '' viewDidLoad'の内部? – trapper

+0

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

答えて

20

編集:viewDidUnloadが廃止され、これは完璧に動作するはずremoveObserver

に代わりdeallocを使用し、私はここでテストしています。

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

テストしたことがあります。

  • viewDidUnloadにブレークポイントを入れて、このような場合は多分にあなたの登録/登録解除コードを移動する(あなたは別のViewControllerからSomeKeyを変更しているので)ビューはあなたに消えていないことを確認してくださいinit/deallocは、VCの仕組みによって異なります。

  • 使用明示的なキーパス@"SomeKey"のようではないSOME_NSSTRING_VARIABLE

+0

私はちょうど完全な電話を(シミュレータで)リセットし、ビルドもきれいにしました。今はうまくいきます。あなたのコードをありがとう。 SOME_NSSTRING_VARIABLEでも動作します –

+1

viewDidUnloadは廃止されました。代わりにdeallocを使用してObserverを削除します – foOg

+0

はい – trapper

3

スウィフトバージョンのような置換:

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

スウィフト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") 
} 
関連する問題