Reputation: 39700
I'm trying to create an NSDictionary that stores objects with keys based on IDs. I know I can use NSNumber objects, but why can't I just use an int instead? Is there some class that supports this? Something like an NSSet almost works, except I can't access it by it's hash value (I've overridden - (NSUInteger) hash
to return the object's ID, which always unique)
I'm basically trying to turn this:
//objects is an NSMutableDictionary
- (id) objectForId:(NSUInteger)id {
return [objects objectForKey:[NSNumber numberWithInt:id]];
}
- (void) addObject:(Object *)foo {
[objects setObject:foo forKey:[NSNumber numberWithInt:id]];
}
into this:
//objects is an NSSet
- (id) objectForId:(NSUInteger)id {
return [objects objectForHash:id];
}
- (void) addObject:(Object *)foo {
[objects addObject:foo];
}
Upvotes: 2
Views: 2365
Reputation: 39700
I ended up creating a category on NSDictionary to store objects based on int keys:
@implementation NSMutableDictionary (IntKeyDictionary)
- (void) setObject:(id)obj forId:(int)id {
[self setObject:obj forKey:[NSNumber numberWithInt:id]];
}
- (void) removeObjectForId:(int)id {
[self removeObjectForKey:[NSNumber numberWithInt:id]];
}
- (id) objectForId:(int)id {
return [self objectForKey:[NSNumber numberWithInt:id]];
}
@end
Upvotes: 3
Reputation: 162712
You'll want to use the C API to NSMapTable after configuring an NSMapTable instance to use integer keys. An example:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMapTable *mt = [NSMapTable mapTableWithKeyOptions: NSPointerFunctionsIntegerPersonality | NSPointerFunctionsOpaqueMemory
valueOptions: NSPointerFunctionsObjectPersonality];
for(NSUInteger i = 0; i<10; i++)
NSMapInsert(mt, (void *) i, [NSNumber numberWithInt: i]);
for(NSUInteger j = 0; j<10; j++)
NSLog(@"retrieved %@", (id) NSMapGet(mt, (void *) j));
[pool drain];
return 0;
}
Note that there appears to be a bug in NSMapTable() where it does not allow 0 to be a key. Oops.
Better documentation of the functional API to NSMapTable is requested in <rdar://problem/7228605>.
A fix for the 0 key problem is documented in <rdar://problem/7228618>
Upvotes: 11
Reputation: 35925
NSDictionary
's setObject:forKey:
already takes the key by id
, which is what it looks like you're doing with your NSSet
equivalent. What about NSDictionary is insufficient for your purposes?
Upvotes: 0