5

在开发 iPhone 应用程序并尝试通过标准 NSUserDefaults 机制保存首选项时,我遇到了非常不一致的结果。我使用的代码几乎直接来自 Erica Sadun 的 iPhone Developer's Cookbook(顺便说一句很棒的书),它看起来像这样:

(无效)更新默认值
{
    NSMutableArray *spells = [[NSMutableArray alloc] init];
    NSMutableArray *locs = [[NSMutableArray alloc] init];

    for (DragView *dv in [boardView subviews])
    {
        [spells addObject:[dv whichSpell]];
        [locs addObject:NSStringFromCGRect([dv frame])];
    }

    [[NSUserDefaults standardUserDefaults] setObject:spells forKey:@"spells"];
    [[NSUserDefaults standardUserDefaults] setObject:locs forKey:@"locs"];
    [[NSUserDefaults standardUserDefaults] 同步];

    [法术释放];
    [位置释放];
}

这些值有时会被保存……有时会被恢复。我无法确切知道什么使它起作用或不起作用。

有没有其他人有类似的经历?关于什么可能使它起作用的任何建议?同步方法是强制写入磁盘并保存值的最佳方法,还是有更好的方法(用于生产和模拟器)。

谢谢瑞恩

4

2 回答 2

2

您应该使用 NSKeyedArchiver 来保存您的数组,例如:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:spells] forKey:@"spells"];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:locs] forKey:@"locs"];
[[NSUserDefaults standardUserDefaults] synchronize];

你还应该确保你的 spells 类实现了 NSCoding 协议(encodeWithCoder: 和 initWithCoder:),如果它是一个自定义类的话。看起来您的 locs 是 NSStrings,可以很好地归档。

你还需要做类似的事情

NSData *dataRepresentingSavedSpells = [currentDefaults objectForKey:@"spells"];
if (dataRepresentingSavedSpells != nil)
{
    NSArray *oldSpells = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedSpells];
}

从默认值加载旧值。

我在退出时使用同步写入磁盘,根据我的经验,它非常可靠。

于 2009-01-24T03:38:44.557 回答
2

在 Mac OS X 上,也可能在 iPhone OS 上,默认数据库只能包含属性列表对象:NSString、NSNumber、NSArray、NSDictionary 和 NSData。

从您的代码片段中不清楚咒语是什么类型,但如果不是上述类型之一,它将不会存储在默认数据库中。您的选择是:

  1. 编写一个方法,将您的对象转换为 plist 表示和从 plist 表示转换。换句话说,一种从对象创建 NSDictionary 的方法和另一种使用 NSDictionary 初始化对象的方法。您还可以选择将其存储为 NSArray 或 NSString。
  2. 使您的对象实现 NSCoding 协议,然后使用 NSKeyedArchiver 将对象转换为 NSData 对象,并使用 NSKeyedUnarchiver 将其转换回来。
于 2009-02-04T09:33:45.523 回答