Using an object's id as a key in NSDictionary


I was working on a utility class and was playing with the idea of using the id of an object (e.g. NSObject) as a key in NSDictionary. Setting it directly doesn’t work though:

NSObject *obj = [[[NSObject alloc] init] autorelease]; // we'll use this as the key

NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease];
[dict setObject:@"a value" forKey:obj]; // won't work

The above will lead to an exception like this:

NSInvalidArgumentException, reason: '-[NSObject copyWithZone:]: unrecognized selector
sent to instance 0x7ca6160'

The solution I arrived at was to use the string representation of the object. Simply casting the object to NSString will not work though:

[dict setObject:@"a value" forKey:(NSString *)obj]; // same exception

Using a new NSString instance will work however:

NSString *key = [NSString stringWithFormat:@"%@", (NSString *)obj]; // use a new NSString
[dict setObject:@"a value" forKey:key]; // works!

Update

curthard89 from Forrst pointed out that it would be better to use [NSObject hash] instead of typecasting to string. The reason is NSDictionary and NSArray string representations can get really long and would be inefficient. I’m now using this technique:

NSNumber *key = [NSNumber numberWithUnsignedInt:[obj hash]];
[dict setObject:@"a value" forKey:key];