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.