2009-08-14 8 views
6

Tôi đã lưu trữ từ điển trong NSUserDefaults và tôi cần thêm/xóa các mục trong từ điển này.Thay đổi các đối tượng trong NSUserDefaults mà không cần tạo và thiết lập lại các bản sao

Nó làm phiền tôi rằng để làm điều này tôi phải tạo bản sao có thể thay đổi toàn bộ từ điển, thay đổi một phần tử và thay thế toàn bộ từ điển bằng bản sao mới.

copy = [[defaults objectForKey:@"foo"] mutableCopy]; 
[copy setObject:… forKey:@"bar"]; 
[defaults setObject:copy forKey:@"foo"]; 

và nó liên quan đến việc sao chép và thiết lập lại nhiều hơn cho các đối tượng sâu hơn trong cấu trúc phân cấp.

Có cách nào tốt hơn không?

Tôi đã cố gắng sử dụng [defaults setValue:… forKeyPath:@"foo.bar"] nhưng điều đó dường như không hoạt động (đối tượng không thể thay đổi được).

Trả lời

5

Tôi thường tạo một lớp tùy chỉnh để giữ tất cả các tùy chọn ứng dụng của mình. lớp có thể tải bản sao có thể thay đổi trong những userDefaults một lần, khi chương trình bắt đầu, và sau đó xử lý tất cả các gia tăng tiết kiệm trên đường đi:

MyPreferences.h

@interface MyPreferences 
{ 
    NSMutableDictionary allPrefs; 
} 
@property (readonly) NSMutableDictionary * allPrefs; 
- (void)load; 
- (void)save; 
@end 

MyPreferences.m

@implementation MyPreferences 
@synthesize allPrefs; 

- (id)init 
{ 
    if ((self = [super init]) == nil) { return nil; } 
    allPrefs = [[NSMutableDictionary alloc] initWithCapacity:0]; 
    return self; 
} 

- (void)dealloc 
{ 
    [allPrefs release]; 
    [super dealloc]; 
} 

- (void)load 
{ 
    // load all mutable copies here 
    [allPrefs setObject:[[defaults objectForKey:@"foo"] mutableCopy] 
       forKey:@"foo"]; 
    // ... 
} 

- (void)save 
{ 
    [defaults setObject:allPrefs forKey:@"app_preferences"]; 
} 

@end 

Tôi tạo một phiên bản của lớp này trong ủy quyền ứng dụng của mình rồi gọi [myPrefs load] khi ứng dụng của tôi khởi chạy. Bất kỳ sở thích thay đổi trong khi chương trình đang chạy có thể được sửa đổi thông qua myPrefs, và sau đó lưu bằng cách gọi [myPrefs save] như mong muốn:

MyPreferences * myPrefs = [myApplication myPrefs]; 
[myPrefs setObject:bar forKeyPath:@"allPrefs.foo.bar"]; 
[myPrefs save]; 

Là một tiền thưởng thêm, bạn có thể cấu trúc lớp MyPreferences bất kỳ cách nào bạn thích, mang lại những lợi ích của Lập trình OO cho toàn bộ các tùy chọn. Tôi đã cho thấy cách dễ dàng ở đây, chỉ cần sử dụng một từ điển có thể thay đổi, nhưng bạn có thể làm cho mỗi sở thích thành một thuộc tính, và làm trước/sau xử lý cho các đối tượng phức tạp hơn như NSColor, ví dụ.