Nat! bio photo

Nat!

Senior Mull.

Twitter RSS

Github

NSCFBoolean hashes incorrectly

What a giant clusterfuck that is.

Here's what NSObject isEqual: dictates about the relationship between -hash and -isEqual:

If two objects are equal, they must have the same hash value. This last point is particularly important if you define isEqual: in a subclass and intend to put instances of that subclass into a collection. Make sure you also define hash in your subclass.

That's the meat and potatoes right there. And this is what happens on 10.4.5.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
   NSAutoreleasePool *pool;
   NSNumber   *a;
   NSNumber   *b;
   
   pool = [NSAutoreleasePool new];
   
   a = [NSNumber numberWithInt:1];
   b = [NSNumber numberWithBool:YES];
   
   NSLog( @"a=%@ (@%p hash=$%X), b=%@ (@%p hash=$%X), [a isEqual:b] == %s",
          a, a, [a hash], 
          b, b, [b hash],
          [a isEqual:b] ? "YES" : "NO");
   
   [pool release];
   return( 0);
}
2006-05-05 12:22:42.800 NSCFBooleanClusterFuck[1673] a=1 (@0x303280 hash=$1), 
b=1 (@0xa073a95c hash=$A073A95C), [a isEqual:b] == YES

NSCFBoolean chooses to inherit the hash from NSObject.

As my customer is running 10.4.6 and noticed the problem, I am pretty sure the same problem is alive and well today.