NSUserDefaults同步未保存问题

10

一名测试人员提交了一个错误报告,说如果他执行某个操作然后通过按住主页和睡眠/唤醒按钮重启他的手机,应用程序将无法保留状态。

我已经能够复现这个问题。[NSUserDefaults synchronize] 被调用,但是当我在重启后重新启动应用程序时,NSUserDefaults中的值没有保存。

有人知道synchronize是否会存储到稍后保存到磁盘的缓冲区吗? 如果是这样,我该如何清除缓冲区(我原以为synchronize和flush是相同的,但显然不是)。

(编辑) 换句话说:

assert([[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == NO);
[[NSUserDefaults standardUserDefaults] setBool: YES forKey: MY_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];

在上述操作后将应用程序保留在前台并重新启动设备,然后重新启动设备并再次运行应用程序。断言应该第二次触发,但有时未能触发。

非常具体地说...我创建了一个单视图应用程序,并将以下代码放置在viewDidLoad中

#define MY_KEY @"MY_KEY"

- (void)viewDidLoad
{
    [super viewDidLoad];
    BOOL key = [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY];
    NSLog(@"[[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == %@", key ? @"YES" : @"NO");
    [[NSUserDefaults standardUserDefaults] setBool: !key forKey: MY_KEY];
    [[NSUserDefaults standardUserDefaults] synchronize];
    NSLog(@"reboot now.");
}

这里是应用程序三次运行的输出结果:

2013-05-31 12:17:44.127 syncTest[162:907] [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == YES
2013-05-31 12:17:44.133 syncTest[162:907] reboot now.
2013-05-31 12:18:49.771 syncTest[128:907] [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == NO
2013-05-31 12:18:49.778 syncTest[128:907] reboot now.
2013-05-31 12:19:41.388 syncTest[124:907] [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == NO
2013-05-31 12:19:41.397 syncTest[124:907] reboot now.

请注意原本的输出是“YES,NO,NO”,但应该是“YES,NO,YES”。


你使用哪个事件来调用 [NSUserDefaults synchronize] 方法? - Ric Perrott
同步应该可以工作,可能需要查看一些代码。你是如何设置和获取数据的? - wattson12
@DanielT。你最终解决了这个问题吗?我也遇到了类似的问题。 - Glen T
我还没有从苹果那里听到任何关于它的消息。我通过将数据保存在CoreData对象中来解决了这个问题。 - Daniel T.
我在2013年5月31日提交了这个bug。苹果公司在2013年6月3日要求提供示例代码,我当天就提交了示例代码。自那以后他们没有回复过我,甚至没有确认收到。 - Daniel T.
显示剩余5条评论
2个回答

2
在我的情况下,我将一些值写入NSUserDefaults中,有些值被保存了,而有些值没有被保存。经过大量搜索,我注意到那些没有被保存的键值对的键名是首字母大写的(如TheKey),而其他的键名都是小驼峰式命名的(如theKey)。当我将键名改为小驼峰式命名(theKey而不是TheKey)时,这些值得以在退出应用程序并重新启动后仍然被保留。我觉得这很奇怪,但在我的情况下行得通。

1
在上面展示的示例代码中,出现问题的关键字完全相同。 - Daniel T.

2

我曾经遇到同样的问题,发现在不同类中有两个[NSUserDefaults standardUserDefaults]对象的引用。因为NSUserDefaults是一个单例类,所以先调用它的类将拥有它。如果你已经有了[code] [NSUserDefaults standardUserDefaults] [/code]的引用,请从第一个引用结束并释放实例,然后在其他类中调用该实例并同步,希望问题可以解决。


1
你会注意到在我的示例代码中,只有一个类引用了NSUserDefaults。所以这并没有回答问题。如果它对你有用,我很高兴。 - Daniel T.
在你的示例代码中,它有一个引用,但我告诉你可能还有其他类也有相同的引用,所以如果你得到了standarduserdefault对象引用,请将该对象设置为nil,然后使用...而且如果你没有在其他地方使用userdefault,那么就必须看看你到底在做什么。 - Khurram Iqbal
1
谢谢您关注这个问题,但是即使在只有一个引用的示例代码中,问题仍然出现,所以显然问题与有多个引用无关。 - Daniel T.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接