UserDefaults.standard值可能无法读取吗?
我知道UserDefaults只是为了保存偏好,但这些偏好是持久的 - 保存在UserDefaults中的值是通过无限数量的应用程序启动维护的,只要应用程序保持安装状态,就可以随时读取它们。对?UserDefaults.standard值可能无法读取吗?
这些值可能会被清除,或者在任何时候都无法正确访问吗?经过多年使用UserDefaults并根据它们所保持的值的一致性,我现在在工作的一天中看到过两次,当我的应用程序启动并检查了一个简单的布尔值时,该值不正确。
if defaults.bool(forKey: "beenLaunched") {
每次启动应用程序时都会运行此代码。如果这个值是真的,我什么也不做,但如果它是假的,我设置一些值,因为这是用户第一次启动应用程序,然后我调用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标准存储)。例如,所有数字(包括布尔值)都以文件NSNumber
的形式存储,并且可以通过object(forKey:)
或bool(forKey:)
检索。如果使用对象方法,并且没有为该值设置任何值,则获得nil
,其布尔值为false
(或0
)。如果你使用布尔方法(你会得到false
)。这意味着无论你走哪条路,如果没有价值或价值false
,你总是会失败。设计你的逻辑(你已经有了 - "beenLaunched"
将是空的,因此false
如果它从未启动),你应该没问题。
至于synchronize()
的建议,请忽略它。除非你使用线程和首选项访问来做一些非常奇怪的事情,或者在设置问题关键字的值/对象后立即中断应用程序,这与此无关。根据文档的第一段,根据需要定期调用synchronize()
。实际上,发生更改后立即调用它。
对于上下文,我的应用程序都没有称为synchronize()
,其中一些应用程序已经够大了。从来没有一个问题。如果你没有非常好的理由自己拨打synchronize()
你几乎肯定不需要它,并试图解释为什么你需要撒在任何地方都经常有趣。
在您的具体情况下,第一次运行多次后卡住的值突然没有发生。是否可以更改应用程序的包标识符或名称?默认值是通过标识符+名称存储的,所以更改会有效地“重置”您应用程序的默认值。你是否已经在模拟器中运行你的应用程序,并且只是在模拟器中重置内容和设置?在您的设备上重新运行设备之前删除了该应用程序?
如果您在swift中工作,则返回nil意味着objectforkey尚未分配任何值。在其他情况下,如果您正确存储了保存的值,它将始终返回适当的值。
并且userdefaults始终可以使用,它永远不会脱机。
在设置值之后是否调用了'NSUserDefaults :: synchronize()'? – Brandon
17年来一直使用Cocoa框架,这不是它的工作原理。 :-)没有麻烦阅读该线程,但没有,它永远不会“脱机”(甚至不知道这是什么意思*)。 –
@Brandon不,我通常不会同步,但从来没有问题 – RanLearns