因为我的 iOS 应用程序更新在 App Store 上线了,所以我很生气,不幸的是,由于我的代码使用 NSUserDefaults
的方式存在错误,它在使用新功能时崩溃了。我的应用程序使用 registerDefaults
,但新功能尝试写入升级后不存在的 key 。如果从头开始安装它工作正常,因为 key 是由 registerDefaults
创建的。
具体来说,我的应用程序使用嵌套字典,因此在更新之前,首选项文件具有以下结构:
<dict>
<key>Alpha</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
<key>Beta</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
<key>Charlie</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
</dict>
—并且在更新后,需要 key Delta:
<dict>
<key>Alpha</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
<key>Beta</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
<key>Charlie</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
<key>Delta</key>
<dict>
<key>Key</key>
<string>Value</string>
</dict>
</dict>
当我的代码试图从用户默认值中检索 Delta 的字典以便向其中写入一些键和值时,它崩溃了。对于这种情况,字典为 nil
,因为更新后它不在首选项文件中。
处理这种情况的最佳做法是什么?在尝试写入并根据需要创建它之前,我是否应该简单地检查 Delta 的字典是否为 nil
,或者是否有更简单的方法?
最佳答案
我用你的数据做了一个简单的测试:
添加一个defaults.plist文件到一个空项目中;
将 defaults.plist 设置为包含 Alpha/Beta/Charlie 键(按照您的示例);
在 appDidFinishLaunching 时使用以下代码:
NSString* path = [[NSBundle mainBundle] pathForResource:@"defaults" ofType:@"plist"]; NSDictionary* factoryPrefs = [NSMutableDictionary dictionaryWithContentsOfFile:path]; [[NSUserDefaults standardUserDefaults] registerDefaults:factoryPrefs]; NSLog(@"Delta Key: %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"Delta"]); //-- store some user custom values NSLog(@"Charlie Key %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"Charlie"]); [[NSUserDefaults standardUserDefaults] setObject:@"test" forKey:@"Charlie"]; NSLog(@"Charlie Key %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"Charlie"]);
运行应用;
结果是:
2013-02-23 17:59:10.795 JigSaw[14747:c07] Delta Key (null)
2013-02-23 17:59:10.797 JigSaw[14747:c07] Charlie Key {
Key = Value;
}
2013-02-23 17:59:10.797 JigSaw[14747:c07] Charlie Key test
然后,我通过添加 Delta 键更改了 defaults.plist 的内容(同样,按照您的示例),并再次构建/运行应用程序(当然没有从设备中删除它)。
结果是:
2013-02-23 18:00:37.840 JigSaw[15040:c07] Delta Key {
Key = Value;
}
2013-02-23 18:00:37.842 JigSaw[15040:c07] Charlie Key test
2013-02-23 18:00:37.842 JigSaw[15040:c07] Charlie Key test
因此,看起来 registerDefaults
将正确处理任何新添加的 key ,如上例所示。
我倾向于认为要么是您错误地使用了 registerDefaults
,要么是您在其他地方做了导致崩溃的事情。
在更一般的层面上,除了测试应用程序更新场景(事后提出建议是微不足道的,我们都通过艰难的方式学习过,不管怎样),对我来说好的做法是确保即使出现错误或不可预见的输入,您的应用程序也不会崩溃。
关于iphone - 应用更新后处理丢失的 NSUserDefault 键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15040098/