I'm using NSMutableDictionary to store what is effectively a descriptor for certain classes, because I'd rather not waste the memory of adding the descriptor to every instance of classes, since only a very small subset of 1000s of objects will have the descriptor.
Unfortunately, given:
MyClass* p = [MyClass thingy];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSString* description = @"blah"; //does this work? If not I'm just simplifying for this example.
[dict setObject:description forKey:p]; // BZZZZT a copy of p is made using NSCopying
MyClass* found = [dict objectForKey:p]; //returns nil, as p becomes a different copy.
So that doesn't work.
I can hack it by passing in an NSNumber like so:
[dict setObject:description forKey:[NSNumber numberWithInt:(int)p]]; // this is cool
But that's not only ugly, but error prone since it is nonstandard.
With that in mind, is there a clean way to do this?
NSValue confirms NSCopying as per NSValue Class Reference. So you can use an instance of NSValue as a key.
Use +valueWithPointer: to wrap the pointer value up.
NSString* foo = @"foo";
id bar = @"bar";
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[dict setObject:@"forKey:foo" forKey:foo];
[dict setObject:@"forKey:bar" forKey:bar];
[dict setObject:@"forKey:[NSValue... foo]" forKey:[NSValue valueWithPointer:foo]];
[dict setObject:@"forKey:[NSValue... bar]" forKey:[NSValue valueWithPointer:bar]];
NSLog(@"%@", [dict objectForKey:foo]);
NSLog(@"%@", [dict objectForKey:bar]);
NSLog(@"%@", [dict objectForKey:[NSValue valueWithPointer:foo]]);
NSLog(@"%@", [dict objectForKey:[NSValue valueWithPointer:bar]]);
Gives
2013-01-24 04:42:14.051 a.out[67640:707] forKey:foo
2013-01-24 04:42:14.052 a.out[67640:707] forKey:bar
2013-01-24 04:42:14.053 a.out[67640:707] forKey:[NSValue... foo]
2013-01-24 04:42:14.053 a.out[67640:707] forKey:[NSValue... bar]
Your problem is that NSDictionary copies its keys. Either make your class implement NSCopying or use a CFMutableDictionary with a key callback that doesn't copy (it's toll-free bridged with NSMutableDictionary, so you can use it exactly the same after it's created).
You may find it easier to use objc_setAssociatedObject
/objc_getAssociatedObject
. They're described here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With