I have a problem with the implementations of
isEqual: and hash in NSDate.
Let's say we have two dates:
NSDate *a, *b;
// This is actually a common case if you are doing
floating point math to generate dates and get small rounding
errors.
a = [NSDate
dateWithTimeIntervalSinceReferenceDate:100000.001];
b = [NSDate
dateWithTimeIntervalSinceReferenceDate:99999.998];
printf("a = %d, b=%d, equal=%d\n", [a hash] , [b hash], [a
isEqual:b]);
// this code will print a = 100000, b = 99999, equal = 1
This breaks the NSDictionary rule that hash of two objects must equal if
they are -isEqual:.
I propose that we change the implementations to this:
- (unsigned) hash
{ return (unsigned)([self timeIntervalSinceReferenceDate]+0.5); } - (BOOL) isEqual: (id)other
{ if (other == nil) return NO; if ([other isKindOfClass: abstractClass] && (int)(otherTime(self)+0.5) == (int)(otherTime(other)+0.5) ) return YES; return NO; } After my change the program's output changes to:
a = 100000, b = 100000, equal = 1
I realize that the dates 100.5 and 100.49 are now not -isEqual:, but you
have to draw the line somewhere, and putting it at .000 as the old code was
worse.
Comments? I will send a patch, so that no retyping is
necessary. |
_______________________________________________ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev