iPhone SDK NSUserDefaults没有保存正确的值

时间:2009-07-23 05:23:17

标签: iphone sdk nsuserdefaults

我可以使用一些帮助。在经历了几次令人沮丧的反复试验之后,我将结果写入NSUserDefaults的结果不一致。

以下是连续的代码行:

        NSLog(@"startTimer(): End Time defaults: %f\n", [defaults floatForKey:kEndTimeKey]);
    NSLog(@"startTimer(): new End Time: %f\n", endTime);
    [defaults setFloat:endTime forKey:kEndTimeKey];
    [defaults synchronize];
    NSLog(@"startTimer(): stored EndTimeKey: %f\n", [defaults floatForKey:kEndTimeKey]);

kEndTimeKey是一个常量字符串。

正如您所看到的,我记录了密钥的当前值,然后记录了我打算存储的值,同步,然后重新读取存储的值。对我来说似乎很简单,但这是调试器输出:

2009-07-22 22:05:43.263 TimerTest3[1584:207] startTimer(): End Time defaults: 0.000000
2009-07-22 22:05:43.266 TimerTest3[1584:207] startTimer(): new End Time: 270018630.916571
2009-07-22 22:05:43.287 TimerTest3[1584:207] startTimer(): stored EndTimeKey: 270018624.000000

我看到原始值0,目标值以571结尾,以及从缓存中读取的值为6秒。

我不确定新默认值的来源。有任何想法吗?我在设备和模拟器上得到了类似的行为。

由于 布拉德

1 个答案:

答案 0 :(得分:1)

你是如何设置endTime的?它是双重的吗?我相对肯定这不是NSUserDefaults问题,而是浮点数学问题。

270018630.916571是16位十进制数字,占用~48位数据来存储尾数。浮点是32位,但是1位是符号位,8位指数,23位尾数。这意味着您看到的值大于浮点数可以容纳的值,并且预计会丢失一定量的精度。即使你将其截断为270018630仍然需要约28位的percision表示,这意味着它必须以大于整数的增量进行舍入。

浮点数不会让你神奇地表达比具有相同位数的整数更大的数字。它们通过改变数字之间的差距并使用元数据(指数)来跟踪它,从而创建存储大量数字的能力。维基百科的工作方式explanation很不错。