NSUserDefaults在应用程序在Appstore的更新中是否会持久化?

111

是这样吗?当您提交应用程序更新到App Store时,NSUserDefaults会被重置,还是它们会重置?

我的应用程序更新后崩溃了,但在完全下载时没有崩溃-因此我正在尝试确定更新会话中可能与全新下载的会话有何不同。

谢谢, Nick。


文档中所述,DocumentsLibrary 中的文件将被保留: http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/RuntimeEnvironment/RuntimeEnvironment.html#//apple_ref/doc/uid/TP40007072-CH2-SW7 - Geri Borbás
6个回答

122

通常情况下,除非用户删除了应用程序,否则它们不会被重置。对于基本数据,NSUserDefaults是保存首选项、日期、字符串等数据的最佳方式。如果您要保存图像和文件,则文件系统是更好的选择。


5
苹果的文档中是否有提到这个地方? - Nick Cartwright
1
抱歉 - 我忘了感谢你的快速回答!- 如果有人能找到任何形式的苹果文档链接,说明这一点,那就太好了...在NSUserDefaults的文档中,没有提到这一点,所以我认为我曾经(错误地)假设默认值会被清除。这似乎是苹果更新应用程序的最安全方式! - Nick Cartwright
这可能是最安全的方式,但如果用户每次应用程序更新时都必须重新设置所有首选项,那将非常令人烦恼。我通常每天有三到四个应用程序更新;我相信其他iPhone用户甚至更多。每次更新都清除首选项基本上会使我的iPhone无法使用。 - Kristopher Johnson
1
文档文件夹中的数据和NSUserDefaults一样容易消失。虽然这两种情况都很少见,但与正常的升级过程完全无关。 - coneybeare
1
谢谢Kristopher - 我同意。我的问题是我使用了NSUserDefaults来存储编程事件,并依赖于它们在应用程序安装时被重置。我在iPhone设备上的所有测试(以及苹果的测试)都将该应用程序测试为新安装。没有任何文档或者测试方式可以测试更新,因此我无法重复我们现在所有客户都遇到的更新崩溃。总之 - 可能是一次通过困难方式学习的教训!! - Nick Cartwright
显示剩余2条评论

8

我相信答案是肯定的,它将持久存在。这也在苹果iPhone OS编程指南的"应用程序目录"章节中得到充分记录。


4
  1. 直接回答问题:是的。
  2. 你的问题: 您的应用程序由于逻辑问题而崩溃。假设您在defaults中存储一个对象,并且应用程序在启动时(或其他地方)检查其值。在更新中,您可以更改检查或使用它的方式,例如,您期望一个值,但对象为nil,反之亦然。这可能会导致SIGABRT或EXC_BAD_ACCESS错误。

3
如果您的CoreData模型发生了更改并且进行了更新,但没有管理迁移,则可能是您的应用程序在更新时崩溃的原因...

我认为这可能是一个情况,而不是NSUserdefault。 - Julian

1
我有类似的经验。我们的应用程序在Settings.Bundle/Root.Plist中存储了版本号。这会通过iPhone Settings应用程序显示出来。我们发现,在安装时,版本号从应用程序包中加载 - 因此版本号是正确的。但是在更新时,版本号不会改变。这会给用户留下正在运行先前版本的应用程序的印象。我们没有将版本号链接到任何逻辑,它仅用于显示(联系中心工作人员在诊断故障时可能会使用它)。
我们的经验是,当用户更新我们的应用程序时,NSUserDefaults不会被清除,但是设置显示也不会得到更新。

0

注意这种情况,当您的应用程序在后台运行时,无法访问存储在NSUserDefaults中的值:

Eric:

关于这个问题已经有很多线程和错误报告了,但是在iOS 9中我又遇到了这个问题。我的应用程序会在后台响应NSURLSession任务和content-available推送而启动。如果我重新启动手机并等待应用程序在后台启动,然后打开应用程序,我发现[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]包含所有系统值,例如AppleITunesStoreItemKinds等,但不包含我设置的任何值。如果我强制退出并重新启动应用程序,则所有我的值都会恢复。是否有任何方法可以避免缓存“空”standardUserDefaults,至少可以确定何时它们被破坏并在不必强制退出应用程序的情况下进行修复?

Eskimo (eskimo1@apple.com):

问题在于NSUserDefaults最终由应用程序容器中的文件支持,而您的应用程序容器受到数据保护的限制。如果您没有采取任何特殊措施,则在iOS 7及更高版本上,您的容器将使用NSFileProtectionCompleteUntilFirstUserAuthentication,这是一个由NSUserDefaults后备存储继承的值,因此您无法在第一次解锁之前访问它。
我认为解决这个问题的最佳方法是避免在可以在后台执行的代码路径中依赖NSUserDefaults。相反,将这些设置存储在您自己的首选项文件中,其中数据保护可以由您明确管理(在这种情况下,这意味着“设置为NSFileProtectionNone”)。
在数据保护环境中,NSUserDefaults存在两个问题:
它是完全抽象的API:其后备存储的存在和位置不被视为该API的一部分,因此您无法明确管理其数据保护。
注意,在最近的OS X版本中,NSUserDefaults由守护程序管理,试图直接操作其后备存储的人遇到了问题。很容易想象同样的事情在某个时候会发生在iOS上。
即使更改数据保护是可能的,NSUserDefaults也没有机制根据您使用数据的上下文对数据进行分类;它是一个“全有或全无”的API。在您的情况下,您不想从所有用户默认设置中删除保护,只是那些需要在第一次解锁之前访问的设置。
最后,如果其中任何数据真正敏感,您应该将其放入钥匙串中。值得注意的是,钥匙串确实有能力逐个项目设置数据保护。

Source: https://webcache.googleusercontent.com/search?q=cache:sR9eZNHpZtwJ:https://forums.developer.apple.com/thread/15685


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接