Использование объекта в качестве ключа для NSDictionary

У меня есть куча Lesson, и класс отлично работает. Существует контроллер просмотра, который работает с этими уроками. Этот контроллер должен знать статус загрузки Lesson, поэтому у нас есть NSDictionary с ключом Lesson as и NSNumber, имеющий процент состояния загрузки.

Это проблема, потому что после того, как вы вставляете Lesson, вы хотите в дальнейшем выполнить поиск этого же Lesson (возможно, в cellForRowAtIndexPath:), чтобы получить прогресс. Это не работает, потому что ключи копируются в NSDictionary.

Хорошо ли сохранять и извлекать ключи с чем-то вроде этого:

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

Или есть лучший подход?

Ответ 1

Я использовал эту технику много раз в прошлом и имел большой успех, обернув ключевые объекты в 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:

(простите форматирование, я на iPhone. Я буду форматировать позже: -)

Ответ 2

Исходя из предложения: "Это не работает, потому что ключи копируются в NSDictionary". Пробовали ли вы реализовать -isEqual: и -hash в своем классе уроков? Я готов поспорить, что если урок, который вы используете для поиска, и скопированный в словаре в качестве ключа оценивает -isEqual: до YES, вы будете в порядке.

Ответ 3

Предполагая, что урок имеет уникальный номер (или идентификатор), сделайте это ключом. Используя NSMutableDictionary, вы можете позже обновить словарь, но записать новый номер с более высоким значением (как обновления Lession), но тот же ключ.

Ответ 4

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