ios - 是否有可能无法读取 UserDefaults.standard 值?

标签 ios iphone swift ipad nsuserdefaults

我知道 UserDefaults 只是为了保存首选项,但这些首选项是持久的 - 保存在 UserDefaults 中的值会在无限次应用程序启动后保持不变,并且只要应用程序保持安装状态就始终可供读取。 . 对吧?

这些值是否有可能在任何时候被清除或无法正确访问?在使用 UserDefaults 多年并依赖于它们持有的值的一致性之后,我现在在一天的工作中看到两次当我的应用程序启动并检查一个简单的 bool 值时,该值不正确。

if defaults.bool(forKey: "beenLaunched") {

此代码会在每次应用启动时运行。如果该值为 true,我什么都不做,但如果它为 false,我会设置一些值,因为这是用户第一次启动应用程序,然后我调用 defaults.set(true, forKey: "beenLaunched") 和defaults.set(0, forKey: "eventsCompleted") 和其他一些值。

我找到了 this thread on the Apple forums其中 Eskimo 说“对于中央 NSUserDefaults 方法,-objectForKey:,结果为 nil 意味着该值不可用,但是无法区分此键不存在和无法获取此值,因为用户默认离线。” (这似乎是针对 background launching while a device is locked 的一个特定案例)

我可以研究一种更安全的方法来保存简单数据,例如 Bool 值、Int 或 String,但是对这些类型的值使用 UserDefaults 一直是简单、直接和可靠的。任何人都可以插话此事吗?如果我相信 UserDefaults 的持久性是错误的?

谢谢!

最佳答案

UserDefaults 不是“服务”;它永远不会对您的应用程序不可用。它写入的文件是 PLIST(因此所有值都根据 PLIST 标准存储)。例如,所有数字(包括 bool 值)都作为 NSNumber 存储到文件中,并且可以通过 object(forKey:)bool(forKey: )。如果您使用对象方法并且没有为该值设置任何内容,您将得到 nil,其 bool 值为 false(或 0)。如果您使用 bool 方法也是如此(您得到 false)。这意味着无论您采用哪种方式,如果没有值或值为 false,您将始终得到 false。围绕它设计您的逻辑(您已经拥有 - "beenLaunched" 将是空的,因此如果它从未启动过则为 false)并且您应该没问题。

至于synchronize()的建议,无视。除非您对线程和首选项访问做了一些非常奇怪的事情,或者您在为问题键设置值/对象后立即中断了应用程序,否则这与此无关。根据文档的第一段,synchronize() 会根据需要定期调用。实际上,它几乎是在更改发生后立即被调用的。

对于上下文,我的应用程序都没有调用过 synchronize() 并且其中一些应用程序已经足够老了可以驱动。从来没有一个问题。如果您没有很好的理由自己调用synchronize(),您几乎可以肯定不需要它并尝试解释为什么您确实需要将它洒在各处是......经常很有趣。

在您的特定情况下,该值在第一次运行多次后突然停滞不前。您是否可能更改了应用程序的包标识符或名称?默认值由标识符+名称存储,因此更改将有效地“重置”您应用程序的默认值。您是否一直在模拟器中运行您的应用程序并且您是否刚刚在模拟器中重置内容和设置?在您的设备上删除应用程序,然后再在设备上重新运行它?

关于ios - 是否有可能无法读取 UserDefaults.standard 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44092335/

相关文章:

ios - 如何从应用程序扩展更新的 sqlite 文件中重新加载主应用程序中的 CoreData 数据?

iphone - 创建基于位置的提醒 : what to do with horizontal accuracy?

iphone - 我可以在 iPhone 上预加载自定义字体以提高性能吗?

ios - 如何将复选框列表添加到 UITextView

swift - 如何显示没有逗号的int?

ios - NSString 到日期的转换

ios - 如何从内存中的 NSData 将 .webarchive 加载到 UIWebView 中?

ios - 如何从 UIImagePickerController 选择多个图像

iphone - 如何更改 UIButton 标题?

ios - 在 Swift 的 TableView 中填充数据时出现问题