ios - UserDefaults 有时被错误读取

标签 ios swift swift3

我一直在开发一个应用程序,可以在应用程序启动之间存储用户数据(用户名等);我将此数据存储在 UserDefaults 中。然而,我最近注意到一个问题:有时,当我运行应用程序时,我会从 UserDefaults.standard.object(forKey:) 中获取一些值,但有时我会获取 nil 当我确实知道那里有东西时。

这对我来说毫无意义。

我在 SO 上搜索了这个问题的答案,但只找到了 this ,这没有帮助。

为了对此进行测试,我制作了一个空应用程序并将以下内容放入 viewDidAppear 中,然后运行该应用程序一次:

UserDefaults.standard.setValue("aValue", forKey: "aKey")

上面一行只是为了确保实际上存储了一个值。然后我从 viewDidAppear 中删除了上面的行,然后我把它放在 didFinishLaunchingWithOptions 中:

print(UserDefaults.standard.object(forKey: "aKey") as? String)

然后我运行了该应用 20 次。如果 print(...) 打印了 nil"aValue",这是我的数据:

✓ 𐄂 𐄂 𐄂 ✓ 𐄂 ✓ ✓ ✓ ✓ ✓ ✓ 𐄂 ✓ ✓ ✓ 𐄂 ✓ ✓ 𐄂

它打印 nil 的概率为 35%,在我看来它也相当随机。

我有两个问题:

为什么会发生这种情况,我该如何解决/预防这种情况?

最佳答案

set 放在 viewDidAppearget 放在 didFinishLaunching 是很疯狂的,因为它们是不相关的并且您对它们发生的顺序一无所知,甚至不知道 viewDidAppear 是否会曾经发生(毕竟不是每个 View Controller 都会出现)。

将它们放在同一个地方以运行测试。例如,让我们将它们都放在 didFinishLaunching 中:

let val = UserDefaults.standard.object(forKey: "aKey") as? String
if val != nil {
    print("got it")
} else {
    print("didn't get it, setting it")
    UserDefaults.standard.set("aValue", forKey: "aKey")
}

您会发现这与您预期的一样有效。

编辑 好吧,多亏了你发布的电影,我们看到了一个复杂的问题:你正在设备上测试它。您通过反复点击 Xcode 中的“运行”按钮而不以连贯的方式停止应用程序来进行测试,这可能会使 Xcode 感到困惑,因此它会进行完全替换,或者它永远不会有机会首先将默认值写入磁盘地方。相反,运行,切换到设备并点击主页按钮,现在切换回 Xcode 并停止。现在再次运行。我想您会发现您会得到更一致的结果。

关于ios - UserDefaults 有时被错误读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40823066/

相关文章:

macos - 如何在整个屏幕上找到 NSView 的位置?

ios - 不调用 UIWebView webViewDidStartLoad 和完成

ios - 如何相对于父 View 的边距将 AddConstraint 添加到按钮,使其看起来距上边距 30 度,距右边距 30 度

ios - 在 UITabBarController 内部,如何从一个 View Controller 切换到另一个 View Controller 并保留选项卡栏?

iphone - iOS 根据设备方向切换 View Controller

ios - 分页时优化数组数据大小

ios - Swift 无法分配给 NSData 类型的不可变值

swift - 实现应用内购买以禁用广告

ios - 如何在转到另一个 View Controller 时停止后台调用?

ios - 以编程方式将 .m4a 转换为 .mp3 文件