2017-05-21 35 views
3

我知道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的持久性?

谢谢!

+1

在设置值之后是否调用了'NSUserDefaults :: synchronize()'? – Brandon

+2

17年来一直使用Cocoa框架,这不是它的工作原理。 :-)没有麻烦阅读该线程,但没有,它永远不会“脱机”(甚至不知道这是什么意思*)。 –

+2

@Brandon不,我通常不会同步,但从来没有问题 – RanLearns

回答

3

UserDefaults不是“服务”;它永远不可用于您的应用程序。它写入的文件是一个PLIST(因此所有值都根据PLIST标准存储)。例如,所有数字(包括布尔值)都以文件NSNumber的形式存储,并且可以通过object(forKey:)bool(forKey:)检索。如果使用对象方法,并且没有为该值设置任何值,则获得nil,其布尔值为false(或0)。如果你使用布尔方法(你会得到false)。这意味着无论你走哪条路,如果没有价值或价值false,你总是会失败。设计你的逻辑(你已经有了 - "beenLaunched"将是空的,因此false如果它从未启动),你应该没问题。

至于synchronize()的建议,请忽略它。除非你使用线程和首选项访问来做一些非常奇怪的事情,或者在设置问题关键字的值/对象后立即中断应用程序,这与此无关。根据文档的第一段,根据需要定期调用synchronize()。实际上,发生更改后立即调用它。

对于上下文,我的应用程序都没有称为synchronize(),其中一些应用程序已经够大了。从来没有一个问题。如果你没有非常好的理由自己拨打synchronize()你几乎肯定不需要它,并试图解释为什么你需要撒在任何地方都经常有趣。

在您的具体情况下,第一次运行多次后卡住的值突然没有发生。是否可以更改应用程序的包标识符或名称?默认值是通过标识符+名称存储的,所以更改会有效地“重置”您应用程序的默认值。你是否已经在模拟器中运行你的应用程序,并且只是在模拟器中重置内容和设置?在您的设备上重新运行设备之前删除了该应用程序?

+0

感谢@JoshuaNozzi的解释和备份,不需要手动调用同步(),但我确信他们不会受到伤害。我没有更改标识符/名称,但很好指出。我在具有各种设备外观的模拟器以及实际设备上快速连续测试该应用程序。我不知道是什么造成了这个问题,但我无法复制这个问题(尽管它发生了两次),我不想怀疑我所知道的一直是保存到PLIST文件的可靠方法。 – RanLearns

+0

自从Swift引入了bool(forKey :),integer(forKey :)和string(forKey :)之后,我已经试过使用那些特定的对象(forKey :),当变量类型是明确的 – RanLearns

-1

如果您在swift中工作,则返回nil意味着objectforkey尚未分配任何值。在其他情况下,如果您正确存储了保存的值,它将始终返回适当的值。

并且userdefaults始终可以使用,它永远不会脱机。