1

我将一个对象存储NSDate在一个NSDictionary. 然后我得到另一个NSDate具有相同日期值的对象,并用它从NSDictionary. 令我惊讶的是,它回来了nil。但是在我的调试会话中揭示的内容更让我震惊:

(lldb) po when
(NSDate *) $34 = 0x0f8be100 2012-05-11 21:08:37 +0000
(lldb) po [newTaskDict objectForKey:when]
(id) $36 = 0x00000000
(lldb) po [newTaskDict allKeys]
(id ) $37 = 0x0f8c1650 <__NSArrayI 0xf8c1650>(
2012-05-11 21:08:37 +0000
)
(lldb) po [[newTaskDict allKeys] lastObject]
(id) $38 = 0x0f8b5ff0 2012-05-11 21:08:37 + 0000
(lldb) p (int)[[[newTaskDict allKeys] lastObject] isEqual:when]
(int) $39 = 0
(lldb) po [[[newTaskDict allKeys] lastObject] class]
(id) $40 = 0x3f4496b0 __NSDate
(lldb) po [当类]
(id) $41 = 0x3f4496b0 __NSDate
(lldb) p (int)[[[newTaskDict allKeys] lastObject] isEqualToDate:when]
(int) $42 = 0
(lldb) p (int)[[[newTaskDict allKeys] lastObject] hash]
(int) $43 = 358463317
(lldb ) p (int)[当散列时]
(int) $44 = 358463317

如您所见,newTaskDict只有一个由原始值键入的条目,NSDate其值为($38):
0x0f8b5ff0 2012-05-11 21:08:37 +0000
并且其哈希值为($43):
35846331

NSDate我用来检索条目的另一个是($34):
0x0f8be100 2012-05-11 21:08:37 +0000
它的哈希是($44):
358463317

除了它们的内存地址之外,这两个不是NSDate完全相同吗?isEqual:($39) 和($42)怎么可能isEqualToDate:为他们返回 NO?

已解决:
这种奇怪的不平衡原来是由sub-second differences. 您必须在已接受的答案下阅读我的第二条评论,因为它真的很有趣,如果您不知道它可能有一天会咬到您。

4

2 回答 2

6

isEqualToDate:还将查看毫秒,您无法通过记录对象看到毫秒,因为描述方法NSDate仅格式化人类友好的字符串,但是日期对象背后有更多信息。

看起来您的两个日期略有不同,即使它们是在同一个运行循环上创建的,也可能发生这种情况,尝试创建一个并在 2 个引用中仅使用一个对象,然后进行第二次测试以检查分别NSDate创建的两个对象 - 甚至一个接一个,他们不应该是平等的。

引用 Apple 文档:

此方法检测日期之间的亚秒级差异。如果要比较粒度较小的日期,请使用 timeIntervalSinceDate: 比较两个日期。

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsdate_Class/Reference/Reference.html

于 2012-05-12T03:03:40.027 回答
1

isEqual to date 以微秒为单位进行比较。如果您需要较低的精度,请使用 timeIntervalSinceDate: 来测试日期是否在微秒、秒、小时、天等范围内。

isEqual 经常使用内存地址本身来决定它是否是同一个对象,因为如果它们有不同的地址,它们就是不同的对象。

于 2012-05-12T03:00:21.460 回答