William Entriken
William Entriken

Reputation: 39243

Using an object as key for NSDictionary

I have a bunch of Lessons and the class works great. There is a view controller that works with these lessons. This controller needs to know the upload status of a lesson so we have a NSDictionary with the Lesson as key and an NSNumber having the percent of upload status.

This is a problem because after you insert a Lesson you want to later do a lookup on that same Lesson (perhaps in cellForRowAtIndexPath:) to get the progress. This does not work because keys are copied in NSDictionary.

Is it good form to save and fetch keys with something like this:

NSNumber *key = [NSNumber numberWithUnsignedInt:[obj hash]];
[dict setObject:@"... upload progress" forKey:key];

Or there a better approach?

Upvotes: 14

Views: 12676

Answers (4)

SmallChess
SmallChess

Reputation: 8106

UIView *view = [[UIView alloc] init];           
NSMapTable *dict = [NSMapTable weakToStrongObjectsMapTable];
[dict setObject:[NSNumber numberWithInt:1234] forKey:view];
NSNumber *x = [table objectForKey:view];

Upvotes: 5

Chris Trahey
Chris Trahey

Reputation: 18290

I have used this technique many times in the past, and have had great success by wrapping the key-objects into an NSValue:

NSValue *myKey = [NSValue valueWithNonretainedObject:anInstance];
id anItem =[myDict objectForKey:myKey];

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsvalue_Class/Reference/Reference.html#//apple_ref/occ/clm/NSValue/valueWithNonretainedObject:

(forgive the formatting; I'm on iPhone. I'll format later :-)

Upvotes: 38

David Hoerl
David Hoerl

Reputation: 41622

Assuming the lesson has a unique number (or identifier) make that the key. Using a NSMutableDictionary, you can then later update the dictionary but writing a new number with a higher value (as the Lession updates) but the same key.

Upvotes: 0

Tim
Tim

Reputation: 60110

Going solely off the sentence: "This does not work because keys are copied in NSDictionary." Have you tried implementing -isEqual: and -hash in your Lesson class? I'm willing to bet that if the Lesson you use for lookup and the copied one in the dictionary as a key evaluate -isEqual: to YES when compared, you'll be fine.

Upvotes: 5

Related Questions