2009-07-17 29 views
50

Giả sử tôi có khóa @ "MyPreference", với giá trị tương ứng được lưu trữ thông qua NSUserDefaults.Ca cao - Thông báo về NSUserThay đổi giá trị mặc định?

Có cách nào để được thông báo khi giá trị được sửa đổi không?

Hoặc nó có thể được thực hiện thông qua các ràng buộc không? (Nhưng trường hợp này, thay vì ràng buộc giá trị cho một phần tử giao diện người dùng, tôi muốn đối tượng của tôi được thông báo về thay đổi, để tôi có thể thực hiện các tác vụ khác.)

Tôi biết rằng NSUserDefaultsDidChangeNotification có thể được quan sát, nhưng điều này dường như là một cách tiếp cận tất cả hoặc không có gì, và dường như không có cơ chế ở đó để lấy cặp khóa-giá trị cụ thể đã được sửa đổi. (. Hãy thoải mái để sửa)

Trả lời

77

gian cả ngày tìm kiếm câu trả lời, chỉ để tìm thấy nó trong 10 phút sau khi đặt ra câu hỏi ...

đi qua một giải pháp thông qua Key-Value-Quan sát:

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

Hoặc, đơn giản hơn (mỗi bình luận dưới đây):

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

Bạn cũng có thể gọi phương pháp này trên '[NSUserDefaults standardUserDefaults]' và không cần phải thêm vào trước các "giá trị." đến đường dẫn chính. Các thông số khác vẫn không thay đổi. –

+6

Tôi không thể làm cho nó hoạt động như Quin đề xuất sử dụng '[NSUserDefaults standardUserDefaults]'. Tuy nhiên, việc thêm chuỗi không cần thiết vì '... forKeyPath: @" values.MyPreference "...' sẽ hoạt động. Ngoài ra, bạn sẽ cần phải thực hiện '- (void) observValueForKeyPath: (NSString *) keyPath ofObject: (id) thay đổi đối tượng: (NSDictionary *) thay đổi bối cảnh: (void *) context;' để thực sự nắm bắt sự kiện. – TrevorL

+0

Hi TrevorL ... mặc dù stringByAppendingString: không cần thiết, nó giúp khi tạo một phương thức chung - (void) observPreference: (NSString *) pref {... [@ "values." stringByAppendingString: pref] ... – Arvin

9

Và nhân viên của Apple nên sử dụng NSUserDefaultsDidChangeNotification thông báo ở đây: https://devforums.apple.com/message/237718#237718

+6

Những bất lợi của điều này là, bạn không thể biết WHICH của các thiết lập đã được thay đổi. – Emmanuel

+2

Có, bạn nghĩ rằng họ sẽ đặt ít nhất (các) khóa đã thay đổi trong từ điển userInfo của NSUserDefaultsDidChangeNotification, nhưng không: "Thông báo này không chứa từ điển userInfo."Thậm chí tệ hơn, đặc điểm kỹ thuật duy nhất khi NSUserDefaultsDidChangeNotification được đăng nói rằng nó được đăng" khi một miền liên tục bị thay đổi ". Có thể mất 20 phút nghiên cứu để xác nhận chính xác điều đó có nghĩa là gì, và sau đó tôi không chắc chắn Hãy tin tưởng nó –

13

Swift:

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

đừng quên loại bỏ người quan sát vì bạn đang giải thích cách tiếp cận hoàn chỉnh – slxl

0

Tôi đồng ý với @DenNukem. Tôi đã sử dụng NSKeyValueObservingOptionNew. Nhưng chức năng này bắt đầu cho tôi lỗi BADACCESS Code = 1 bất cứ nơi nào tôi sử dụng NSUserdefault để lưu các đối tượng khác. Trong trường hợp bạn đang sử dụng Trình theo dõi giá trị khóa, chỉ cần biết vấn đề Zombie trên NSUserDefaults.

Dưới đây là liên kết với các giải pháp: NSUserDefaults and KVO issues

Các vấn đề liên quan