0

请注意,更新 3 可能是最相关的

我使用 nsdate 对象设置NSTimeInterval托管对象的属性setValue:forKey:

当我尝试获取值时,我得到了奇怪的东西,在运行时这个

NSLog(@"[managedObject valueForKey:@\"startTime\"] : %@, [NSDate dateWithTimeIntervalSince1970:[managedObject startTime]]: %@",
[managedObject valueForKey:@"startTime"],[NSDate dateWithTimeIntervalSince1970:[managedObject startTime]]);

退货

[managedObject valueForKey:@"startTime"] : 2012-07-14 08:13:05 +0000,
[NSDate dateWithTimeIntervalSince1970:[managedObject startTime]]: 1981-07-14 08:13:05 +0000

更新 1
返回的值[managedObject valueForKey:@"startTime"]是正确的。但是我更喜欢使用[NSDate dateWithTimeIntervalSince1970:[managedObject startTime]]或类似的东西,以便它的类型更强大。

我相信[managedObject startTime]返回不正确的值 => 363954111.000000
但是我用这样的东西设置它:

managedObject setValue:1342261311 forKey:@"startTime"

值得注意的是,我不确定这是否不正确,因为[managedObject valueForKey:@"startTime"]返回了正确的 NSDate 对象。

更新 2
我记录了 KVC 和.语法返回的双精度值。

managedObject.startTime = 363954111.000000
valueForKey timeIntervalSince1970 = 1342261311.000000

更新3
好的,我已经设置了一个测试,开始时间是这样设置的entity.startTime = [[NSDate dateWithTimeIntervalSince1970:1342261311] timeIntervalSince1970];,结束时间是这样设置的[entity setValue:[NSDate dateWithTimeIntervalSince1970:1342261311] forKey:@"endTime"];

当我将它们写入日志时,我得到了这个start = 1342261311.000000, end = 363954111.000000

似乎 NSDate 对象被错误地解包,有没有人见过这个?

4

4 回答 4

2

这里的问题是它valueForKey:旨在与对象值一起使用,实际上它返回一个id.

为方便起见,valueForKey:将原始类型(如整数和双精度数)包装在NSNumber对应的对象中。

您看到两个不同值的原因是它valueForKey:返回一个id,它本质上是一个指针,指向NSNumber恰好存储在内存中的位置。然后,您的代码只需获取这个任意内存地址,并以某种方式将其解释为双精度,然后从中构造一个NSDate

startTime另一方面,直接调用访问器方法会double毫不费力地返回 。

如果你想使用valueForKey:,你可以做这样的事情来获得真正的价值:

NSTimeInterval tiv = [[managedObject valueForKey:@"startTime"] doubleValue];

然后从那里开始工作。

我实际上有点惊讶编译器没有对此发出警告。Apple 最新的编译器已经非常擅长捕捉此类问题。

于 2012-07-14T10:22:46.013 回答
1

这是时代差异的问题。NSDate 使用 2001 年 1 月 1 日作为纪元。因此,当我获得价值时,我使用的是 unix epoch (1970)。这给了我价值观上的差异。

当 KVC 使用 NSDate 对象解包和包装 NSTimeInterval 时,它使用 NSDate 2001 纪元。

因此,而不是使用dateWithTimeIntervalSince1970dateWithTimeIntervalSinceReferenceDate在获取价值时使用。

于 2012-07-15T06:48:47.803 回答
0

NSTimeInterval是 double 的类型定义

typedef double NSTimeInterval;

您不能将标量直接存储在核心数据中,但您必须将它们包装在 aNSNumber 中,或者在您的情况下使用 a 可能更容易NSDate

于 2012-07-14T08:47:52.287 回答
0

如果 startTime 是一个 NSTimeInterval (而不是一个 NSDate),你正在比较两个不同的东西,一个双精度对象和一个 NSDAte 对象。

[managedObject valueForKey:@"startTime"]将返回一个 NSTimeInterval,一个原语(顺便说一下,你应该用 %f 打印它)。

[NSDate dateWithTimeIntervalSince1970:[managedObject startTime]]会给你一个NSDate。

如果你真的想比较两者,你应该使用[NSDate dateWithTimeIntervalSince1970:[managedObject valueForKey:@"startTime"]]正确比较两个 NSDate 对象。

于 2012-07-14T09:46:25.387 回答