具有相同日期值和相同散列的两个NSDate如何不相等?

时间:2012-05-12 02:57:48

标签: ios comparison nsdate

我将一个NSDate键下的对象存储在NSDictionary中。然后我得到另一个NSDate具有相同的日期值,并用它从NSDictionary中检索对象。令我惊讶的是,它返回nil。但是在我的调试会议期间发现的内容让我更加震惊:

  

(lldb)po时   (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 __NS日期
  (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)和isEqualToDate:($ 42)如何为他们返回NO?

解决


这种奇怪的不确定性原来是由sub-second differences引起的。你必须在接受的答案下阅读我的第二条评论,因为它真的很有趣,如果你不知道它,有一天它可能会咬你。

2 个答案:

答案 0 :(得分:6)

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

看起来你的两个日期略有不同,即使它们是在同一个运行循环上创建的,也可能发生这种情况,尝试创建一个并在2个引用中只使用一个对象,然后再进行第二次测试以检查两个{{ 1}}单独创建的对象 - 即使是一个接一个,它们也不应该相等。

引用Apple文档:

  

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

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

答案 1 :(得分:1)

isEqual to date比较微秒。如果您需要较低的精度,请使用timeIntervalSinceDate:来测试彼此之间的微秒,秒,小时,天等范围内的日期。

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