iphone - 应用更新后处理丢失的 NSUserDefault 键

标签 iphone ios cocoa-touch nsuserdefaults

因为我的 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,或者是否有更简单的方法?

最佳答案

我用你的数据做了一个简单的测试:

  1. 添加一个defaults.plist文件到一个空项目中;

  2. 将 defaults.plist 设置为包含 Alpha/Beta/Charlie 键(按照您的示例);

  3. 在 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"]);
    
  4. 运行应用;

结果是:

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/

相关文章:

iphone - SQLite 核心数据性能随时间的变化

ios - 如何创建新收藏集?

objective-c - 以编程方式从 ARC 中的导航堆栈中删除 viewController

ios - 如何在 iOS 中删除 UITableViewCell 的 No Result TableView?

iphone - 如何设置iPhone视频输出图像大小

ios - iPhone 4、5、5s 和 6+ 模拟器错位节点

iphone - 动画化 UIView 过渡,例如将点扩展为圆圈

ios - 如何找到 NSMutableArray 的最小和最大对象

ios - 如何从嵌套的 collectionView 单元格开始?

iPhone:如何使用 NSUserDefaults 存储 UIImage?