Change objects in NSUserDefaults without creating and re-setting copies

故事扮演 提交于 2019-12-21 13:43:14

问题


I've got dictionary stored in NSUserDefaults and I need to add/remove items in this dictionary.

It bothers me that to do this I have to create mutable copy of entire dictionary, change one element and replace entire dictionary with new copy.

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

and it involves even more copying and re-setting for objects deeper in the hierarchy.

Is there a better way?

I've tried to use [defaults setValue:… forKeyPath:@"foo.bar"] but that doesn't seem to work (object is not mutable).


回答1:


I usually create a custom class to hold all of my application preferences. That class can load mutable copies of the userDefaults once, when the program starts, and then handle all of the incremental saves along the way:

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

I create an instance of this class in my application delegate and then call [myPrefs load] when my application launches. Any preferences changed while the program is running can be modified through myPrefs, and then saved by calling [myPrefs save] as desired:

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

As an added bonus, you can structure the MyPreferences class any way you like, bringing the benefits of OO programming to the whole set of preferences. I showed the easy way here, simply using a mutable dictionary, but you can make each preference into a property, and do pre/post processing for more complicated objects like NSColor, for instance.



来源:https://stackoverflow.com/questions/1277755/change-objects-in-nsuserdefaults-without-creating-and-re-setting-copies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!