点语法和valueForKey之间的区别

时间:2012-07-14 08:31:21

标签: objective-c ios core-data key-value-coding nstimeinterval

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

使用NSTimeInterval

使用nsdate对象设置托管对象的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和.语法返回的double值。

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 个答案:

答案 0 :(得分:2)

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

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

您看到两个不同值的原因是valueForKey:返回id,它实际上是指向内存中NSNumber恰好存储的位置的指针。然后你的代码只接受这个任意的内存地址,并以某种方式将其解释为double,然后构造一个NSDate

另一方面,直接调用startTime访问者方法会返回double而不再进行任何操作。

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

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

然后从那里开始工作。

我实际上有点惊讶,编译器没有发出关于此的警告。 Apple的最新编译器已经非常善于捕捉这样的问题。

答案 1 :(得分:1)

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

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

所以不要使用dateWithTimeIntervalSince1970 获取值时我使用了dateWithTimeIntervalSinceReferenceDate

答案 2 :(得分:0)

NSTimeInterval是double的typedef

typedef double NSTimeInterval;

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

答案 3 :(得分:0)

如果startTime是NSTimeInterval(而不是NSDate),那么你要比较两个不同的东西,一个是double和一个NSDAte对象。

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

[NSDate dateWithTimeIntervalSince1970:[managedObject startTime]]将返回NSDate。

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