带有XCode 8 GM的iOS 10导致NSUserDefaults间歇性不起作用 [英] iOS 10 with XCode 8 GM caused NSUserDefaults to intermittently not work

查看:257
本文介绍了带有XCode 8 GM的iOS 10导致NSUserDefaults间歇性不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意::我在Stack Overflow上看到过许多其他帖子,内容涉及在Swift中将NSUserDefaults重命名为UserDefaults或直到重新启动后才能在模拟器上工作.无论如何,这不是重复的. SO所针对的许多问题都来自4年前.我的问题是今年以来针对iOS 10的,因为它始终适用于较旧的版本.我已经在我的问题中提到过,我的问题不是这些问题的重复,因为这些问题很快就是模拟器错误,而我的问题是关于设备目标C的错误. 在标记为重复之前,请先阅读问题

NOTE: I have seen many other posts on Stack Overflow about NSUserDefaults being renamed to UserDefaults in Swift or not working on simulator until a restart. This is not a duplicate by anyway. Many of the questions SO is tagging against is from 4 years ago. My question is specific to iOS 10 from this year as this has always worked in older versions. I have mentioned in my question already that my question is not a duplicate of those questions as those were simulator bugs in swift and my issue is on device objective C bug. Please read the questions before marking as duplicate

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

My issue is different as I am able to reproduce this on objective C and on physical device itself.

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

I created a brand new project from scratch for this test. I placed this code in the viewDidLoad of a view controller:

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次,再失败一次,依此类推.

Now if I run the app about 10 times, few times it finds the checkIfInitialized and sometimes it doesn't. No exact number on how many times it fails as it might work 3 times then fail next 2 times then work 4 times and fail once and so on.

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

Now something I have noticed (not 100% sure though) that the issue only seems to happen when I am testing connected via Xcode. If I run by launching the app by clicking the app icon on device without Xcode, then it seems to work fine but I can't be 100% sure.

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

I noticed this error occur sometimes:

[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

如果要测试它,我的保管箱上有一个非常简单的项目. 我建议进行大约10到15次测试以重现此问题.

I have this very simple project on my dropbox if you want to test it out. I would suggest testing about 10-15 times to reproduce this issue.

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

这在iOS 9上完全可以正常运行,因此肯定与iOS 10有关.

This works completely fine on iOS 9 so definitely something to do with iOS 10.

编辑 已记录错误:28287988

苹果DTS小组的回复:

首先,您应该首先确定standardUserDefaults还是 valueForKey失败.我的猜测是"standardUserDefaults"是 返回NULL,如果是这种情况,那就是你 一般应提防.值得注意的是,standardUserDefaults 如果首选项文件在加密,则将返回NULL. 应用程序当前运行的环境(例如,首选项 设置为"NSFileProtectionComplete",并且该应用程序正在 背景).对于仅标准前景而言,这不应该是一个问题. 应用程序,但还是要注意.

First off, you should first determine whether standardUserDefaults or valueForKey is failing. My guess is that "standardUserDefaults" is returning NULL and, if that’s the case, then that’s something you should be guarding against generally. Notably, standardUserDefaults will return NULL if the preference file is encrypted in the environment the app is currently running in (for example, preferences is set to "NSFileProtectionComplete" and the app is running in the background). That shouldn’t be an issue for standard foreground-only apps, but it’s something to be aware of anyway.

很有可能Xcode实际上是在此引发问题. Xcode通过以下方式极大地复杂化了应用启动环境: 与标准应用程序的发布非常不同.我的猜测是 基本上是由Xcode的时机触发,从而产生了预期的 应用启动过程中的情况,但如果您想对它进行更正式的测试 尝试在applicationDidFinishLaunching中设置一个断点 并在您点击调试器后继续进行调试.我的猜测是 只是添加会干扰时间,足以阻止问题的发生 发生.有点.仅在iOS 9可以实现的意义上才是iOS 10 从不打印该日志消息,但这是因为该日志消息是 在iOS 10中添加了代码.代码本身与我所使用的iOS 9.3足够相似 怀疑(至少在理论上)完全相同的行为是可能的 iOS 9.

It’s very likely that Xcode is actually inducing the problem here. Xcode vastly complicates the app launching environment in a way that’s VERY different than a standard app launch. My guess is that this is basically being triggered by Xcode’s timing inducing an an expected situation during the app launch, but if you want a more formal test of that try setting a single breakpoint in applicationDidFinishLaunching and continuing in the debugger as soon as you hit it. My guess is just adding that disrupts the timing enough to stop the problem from happening. Sort of. It’s iOS 10 only in the sense that iOS 9 will never print that log message, but that’s because the log message was added in iOS 10. The code itself is similar enough to iOS 9.3 that I suspect exactly the same behavior is (at least in theory) possible in iOS 9.

推荐答案

是的,这绝对是可重现的错误.

Yes, this is definitely a reproducible bug.

  • 这是在Xcode 8和iOS 10的GM版本中发生的.
  • 不是与Swift相关的链接问题.
  • 这不是不是有关模拟器Beta版的链接问题.
  • It happens with the GM release of Xcode 8 and iOS 10.
  • It is not the linked question referring to Swift.
  • It is not the linked question referring to beta versions of the Simulator.

该错误发生在设备和模拟器上.这是断断续续的:保存将进行六次,然后失败.与您不同,我没有收到无法写入密钥"消息.

The bug happens on devices and on the Simulator. It is intermittent: saving will work six times and then fail. Unlike you, I did not get the "failed to write key" message.

在没有Xcode的设备上直接操作时,也会发生该错误.实际上,这就是我发现它的方式.

The bug also occurs when operating directly on the device without Xcode. This is in fact how I discovered it.

您应该将错误报告给Apple ,尤其是因为您有一个简短的程序可以将其重现.我会做同样的事情.

You should report a bug to Apple, especially since you have a short program that will reproduce it. I will do the same.

一个主要区别:在我的情况下,失败是写作的默认操作.先前写入的值保留在NSUserDefaults中.有时,一个键被成功写入,而另一个则保持不变.

One key difference: In my case the failure is in writing the default. The previously written value remains in NSUserDefaults. Sometimes one key is successfully written while another is unchanged.

这篇关于带有XCode 8 GM的iOS 10导致NSUserDefaults间歇性不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆