【问题标题】:iOS 10 with XCode 8 GM caused NSUserDefaults to intermittently not work带有 XCode 8 GM 的 iOS 10 导致 NSUserDefaults 间歇性不起作用
【发布时间】:2016-09-12 19:36:31
【问题描述】:

注意:我在 Stack Overflow 上看到过很多其他帖子,关于 NSUserDefaults 在 Swift 中被重命名为 UserDefaults 或在重新启动之前无法在模拟器上工作。无论如何,这不是重复的。 SO 所针对的许多问题都来自 4 年前。我的问题是从今年开始针对 iOS 10 的,因为这在旧版本中一直有效。我已经在我的问题中提到我的问题不是这些问题的重复,因为这些问题是 swift 中的模拟器错误,而我的问题是设备目标 C 错误。 请在标记为重复之前阅读问题

我的问题不同,因为我能够在目标 C 和物理设备本身上重现此问题。

我为此测试从头开始创建了一个全新的项目。我将此代码放在视图控制器的viewDidLoad 中:

if (![[NSUserDefaults standardUserDefaults] valueForKey:@"checkIfInitialized"]){
    NSLog(@"setting checkIfInitialized as not exist");
    [[NSUserDefaults standardUserDefaults] setValue:@"test" forKey:@"checkIfInitialized"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    self.view.backgroundColor=[UIColor redColor];
    self.mylabel.text=@"NSUserDefaults was NOT there, try running again";
} else {
    NSLog(@"checkIfInitialized exists already");
    self.view.backgroundColor=[UIColor blueColor];
    self.mylabel.text=@"NSUserDefaults was already there this time, try running again";
}

现在,如果我运行该应用程序大约 10 次,它会找到 checkIfInitialized 的几次,有时却找不到。没有确切的失败次数,因为它可能工作 3 次,然后失败 2 次,然后工作 4 次,失败一次,依此类推。

现在我注意到(虽然不是 100% 肯定),这个问题似乎只在我通过 Xcode 测试连接时发生。如果我通过在没有 Xcode 的设备上单击应用程序图标来启动应用程序来运行,那么它似乎可以正常工作,但我不能 100% 确定。

我注意到这个错误有时会发生:

[User Defaults] Failed to write value for key checkIfInitialized in CFPrefsPlistSource<0x1700f7200> (Domain: com.xxxx.appname, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null)): Path not accessible, switching to read-only

如果你想测试一下,我的 Dropbox 上有这个非常简单的项目。 我建议测试大约 10-15 次以重现此问题。

https://www.dropbox.com/s/j7vbgl6e15s57ix/nsuserdefaultbug.zip?dl=0

这在 iOS 9 上完全可以正常工作,因此肯定与 iOS 10 有关。

编辑 记录的错误:28287988

来自苹果 DTS 团队的回应:

首先,您应该首先确定是standardUserDefaults 还是 valueForKey 失败。我的猜测是“standardUserDefaults”是 返回 NULL,如果是这样,那你就是 一般应提防。值得注意的是,standardUserDefaults 如果首选项文件在 应用程序当前运行的环境(例如,首选项 设置为“NSFileProtectionComplete”并且应用程序正在运行 背景)。这不应该是标准前台的问题 应用程序,但无论如何都需要注意。

Xcode 很可能实际上在这里引发了问题。 Xcode 极大地复杂化了应用程序的启动环境 与标准应用程序启动非常不同。我的猜测是,这是 基本上是由 Xcode 的时序触发的 应用程序启动期间的情况,但如果您想要更正式的测试 尝试在 applicationDidFinishLaunching 中设置单个断点 并在您点击它后立即继续调试器。我的猜测是 只是添加它会破坏足够的时间以阻止问题 正在发生。有点。 iOS 10 只是在 iOS 9 将 从不打印该日志消息,但那是因为日志消息是 在 iOS 10 中添加。代码本身与 iOS 9.3 非常相似,我 怀疑完全相同的行为(至少在理论上)可能在 iOS 9。

【问题讨论】:

  • 问题重复。仅仅因为链接问题的答案对您没有帮助并不意味着您的问题以前没有被问过。我看到您已经编辑了您的问题,以说明您为什么认为这不是骗局。希望有人能来解决您的问题。
  • 您显然没有阅读链接的问题,因为它与 Swift 无关。
  • 绝对不是其他问题的重复,这些问题涉及 Swift 语言更改或 iOS 模拟器之间的不兼容。这可以在设备和模拟器中重现,并且确实是间歇性的。
  • 感谢@PranoyC,这很有用

标签: ios objective-c xcode nsuserdefaults ios10


【解决方案1】:

是的,这绝对是一个可重现的错误。

  • 这发生在 Xcode 8 和 iOS 10 的 GM 版本中。
  • 不是链接的问题是指 Swift。
  • 不是链接的问题指的是模拟器的 beta 版本。

该错误发生在设备和模拟器上。它是间歇性的:保存将工作六次,然后失败。与您不同的是,我没有收到“写入密钥失败”的消息。

在没有 Xcode 的设备上直接操作时也会出现该错误。这实际上是我发现的。

您应该report a bug to Apple,尤其是因为您有一个可以重现它的短程序。我也会这样做。

一个关键区别:在我的例子中,失败是在编写默认值。之前写入的值保留在 NSUserDefaults 中。有时一个密钥被成功写入,而另一个没有改变。

【讨论】:

  • 感谢更新!几分钟前我刚刚在 Apple 上记录了 DTS,因为现在我知道我不是唯一面临这个问题的人。如果他们认为这也应该是一个错误,那么这将是一个相当大的错误并导致应用程序出现许多问题。
  • 我刚刚报告了一个错误 28287988 并记录了一个 DTS。将更新我发现的内容。
  • 这里有错误 28289469。
  • 如果您有兴趣,我添加了苹果 DTS 团队对我的问题的回复!
  • 你拯救了我剩下的头发!!!在过去的几天里,我一直在试图找出 wtf 正在发生的事情。我开始怀疑某种 iOS 错误,因为发生了一些不应该发生的事情。我在该领域有一个应用程序,并且由于在 AppDelegate 初始化期间间歇性未能将更改写入 NSUserDefaults 以支持对现有功能的更改而导致的问题而被用户扩眼。我是第 3 次尝试,但仍然被我的用户拍打......至少现在我知道为什么并且有更好的机会实施解决方法。
【解决方案2】:

来自我自己的支持请求的类似非常智能的 DTS 响应。基本上,使用 Xcode 杀戮比设备上自然发生的任何事情(甚至是双击 Home-click-and-upwipe 方法)更具杀戮性,并且由于当 Xcode 停止它时一切都会突然崩溃,所以 NSUserDefaults 的懒惰编写可能会失败,或者只完成了一半。

事实上,在不涉及 Xcode 的情况下对应用程序进行纯设备测试表明,当应用程序终止时,所有内容都正确写入 NSUserDefaults。

我已经关闭了自己的错误报告。

【讨论】:

    猜你喜欢
    • 2017-01-15
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2014-12-06
    • 2013-06-14
    • 2023-03-20
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多