更改 NSUserDefaults 中的对象而不创建和重新设置副本

Posted

技术标签:

【中文标题】更改 NSUserDefaults 中的对象而不创建和重新设置副本【英文标题】:Change objects in NSUserDefaults without creating and re-setting copies 【发布时间】:2009-08-14 13:07:54 【问题描述】:

我的字典存储在 NSUserDefaults 中,我需要在该字典中添加/删除项目。

困扰我的是,为此我必须创建整个字典的可变副本、更改一个元素并用新副本替换整个字典。

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

它涉及到对层次结构更深层次的对象进行更多的复制和重新设置。

有没有更好的办法?

我尝试使用[defaults setValue:… forKeyPath:@"foo.bar"],但这似乎不起作用(对象不可变)。

【问题讨论】:

【参考方案1】:

我通常创建一个自定义类来保存我所有的应用程序偏好。该类可以在程序启动时加载 userDefaults 的可变副本一次,然后在此过程中处理所有增量保存:

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

我在我的应用程序委托中创建了这个类的一个实例,然后在我的应用程序启动时调用[myPrefs load]。在程序运行时更改的任何首选项都可以通过myPrefs 进行修改,然后根据需要通过调用[myPrefs save] 进行保存:

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

作为额外的好处,您可以按照自己喜欢的方式构建MyPreferences 类,从而将OO 编程的好处带到整个偏好设置中。我在这里展示了一种简单的方法,只需使用可变字典,但您可以将每个偏好设置为一个属性,并对更复杂的对象(例如 NSColor)进行前/后处理。

【讨论】:

以上是关于更改 NSUserDefaults 中的对象而不创建和重新设置副本的主要内容,如果未能解决你的问题,请参考以下文章

如何从javascript(nodejs)程序调用python,而不创建子进程

如何使用 NSUserDefaults 注册用户默认值而不覆盖现有值?

如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?

如何在 NSUserDefaults 中绑定 NSDictionary 中的对象?

如何从 Xamarin.iOS 中的 iOS 扩展调用 NSUserDefaults Observer

使用现有对象作为突变的输入