I stored an object under one NSDate key in an NSDictionary. I then got another NSDate with the same date value and used it to retrieve the object from the NSDictionary. To my surprise, it returned nil. But what was revealed during my debug session blew my mind even more:
(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 [when class]
(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)[when hash]
(int) $44 = 358463317
As you can see, newTaskDict has only one entry keyed by the original NSDate whose value is($38):
0x0f8b5ff0 2012-05-11 21:08:37 +0000
and whose hash is($43):
35846331
The other NSDate I used to retrieve the entry is($34):
0x0f8be100 2012-05-11 21:08:37 +0000
and its hash is($44):
358463317
Aren’t these two NSDate exactly the same except for their memory addresses? How could isEqual:($39) and isEqualToDate:($42) return NO for them?
Solved:
This odd unequelness turned out to be caused by sub-second differences. You must read my second comment under the accepted answer because it is really interesting and it might bite you someday if you don’t know it.
isEqualToDate:will also look at the milliseconds, which you cannot see by logging the object since the description method ofNSDateonly formats a human friendly string, however there is more information behind the date object.It would seem your two dates are slightly different, this can happen even if they were created on the same run loop, try to create one and use just one object in 2 references, and then a second test to check two
NSDateobjects created separately – even one after the other, they should not be equal.to Quote Apple documentation:
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsdate_Class/Reference/Reference.html