2009-07-17 295 views
50

比方說,我有一個鍵@「MyPreference」,通過NSUserDefaults存儲相應的值。Cocoa - 關於NSUserDefaults值更改的通知?

當值被修改時是否有通知的方法?

或者可以通過綁定來完成嗎? (但是這種情況下,我不希望將值綁定到UI元素,而是希望我的對象得到更改通知,以便我可以執行其他任務。)

我知道NSUserDefaultsDidChangeNotification可以被觀察到,但是這個似乎是一種全有或全無的方法,並且似乎沒有一種機制可以獲得被修改的特定鍵 - 值對。 (隨時糾正)

回答

77

整天都在尋找答案,只問一個問題,10分鐘後找到它......

遇到了一個解決方案,通過鍵 - 值觀測:

[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self 
    forKeyPath:@"values.MyPreference" 
    options:NSKeyValueObservingOptionNew 
    context:NULL]; 

,或者更簡單(根據註釋如下):

[[NSUserDefaults standardUserDefaults] addObserver:self 
             forKeyPath:@"MyPreference" 
              options:NSKeyValueObservingOptionNew 
              context:NULL]; 
+14

您也可以致電`[NSUserDefaults的standardUserDefaults]`這個方法,而不必預先設置「值」。到關鍵路徑。其他參數保持不變。 – 2011-02-26 06:51:17

+6

我不能像Quin建議使用`[NSUserDefaults standardUserDefaults]`一樣工作。然而,字符串附加不需要,因爲`... forKeyPath:@「values.MyPreference」...`將起作用。另外,你需要實現` - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;`實際捕獲事件。 – TrevorL 2011-06-16 19:30:55

+0

嗨TrevorL ...即使stringByAppendingString:沒有必要,它有助於創建一個通用的方法 - (void)observePreference:(NSString *)pref {... [@「values。」 stringByAppendingString:pref] ... – Arvin 2012-01-15 02:05:16

13

斯威夫特:

override func viewDidLoad() { 
    super.viewDidLoad() 
    NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "THE KEY", options: NSKeyValueObservingOptions.New, context: nil) 
} 

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { 
    // your logic 
} 

deinit { 
    NSUserDefaults.standardUserDefaults().removeObserver(self, forKeyPath: "THE KEY") 
} 
0

我同意@DenNukem。我正在使用NSKeyValueObservingOptionNew。但是,爲了保存其他對象,無論我使用NSUserdefault,該函數都開始爲我提供BADACCESS Code = 1錯誤。如果您使用的是Key Value Observer,只需注意NSUserDefaults上的殭屍問題。

這裏是鏈接到解決方案: NSUserDefaults and KVO issues