Могу ли я изменить ключ NSDictionary?

У меня есть объект NSDictionary, который заполняется экземплярами NSMutableString для его ключей и объектов. Мне удалось изменить ключ, изменив исходный NSMutableString с помощью метода setString:. Однако ключ остается неизменным независимо от содержимого строки, используемой для первоначальной установки ключа.

Мой вопрос в том, защищен ли ключ от изменения, что означает, что он всегда будет одним и тем же, если я не удалю его и не добавлю другой в словарь?

Спасибо.


person Mark Reid    schedule 09.05.2010    source источник
comment
Никогда не пытайтесь изменить ключ в словаре. Если вы это сделаете, возможно, что словарь больше не сможет его найти.   -  person JeremyP    schedule 10.05.2010
comment
Не делай этого, никогда. Понятно. Это было частью упражнения, чтобы выяснить, были ли сделаны поверхностные или глубокие копии объекта NSDictionary. Я получил ответ в порядке, но не понял, что происходит и почему с ключом. Благодарим вас за вклад.   -  person Mark Reid    schedule 10.05.2010


Ответы (3)


Ключи -copy'd, когда элементы установлены, поэтому вы не можете изменить его впоследствии, это бесполезно.

Методы, которые добавляют записи в словари — будь то часть инициализации (для всех словарей) или во время модификации (для изменяемых словарей) — копируют каждый ключевой аргумент (ключи должны соответствовать протоколу NSCopying) и добавляют копии в словарь. Каждый соответствующий объект-значение получает сообщение о сохранении, чтобы гарантировать, что он не будет освобожден до того, как словарь завершит работу с ним.

Вы можете использовать CFDictionary с kCFTypeDictionaryKeyCallBacks или просто заменить элемент:

id value = [dictionary objectWithKey:oldKey];
[dictionary setObject:value withKey:newKey];
[dictionary removeObjectForKey:oldKey];
person kennytm    schedule 09.05.2010
comment
Итак, что вы говорите о том, что ключ неизменен независимо от того, изменчива ли фактическая коллекция, является ли она изменчивой или неизменной? - person Mark Reid; 09.05.2010

Вместо этого попробуйте использовать NSMutableDictionary.

person Alex Reynolds    schedule 09.05.2010
comment
Спасибо, но это не проблема для того, как я его использую. Должен был сказать, что я пытался использовать оба типа, и что в этом случае я использую метод копирования mutableCopy, а затем пытаюсь изменить полученный NSMutableDictionary. Извини, я виноват. - person Mark Reid; 09.05.2010

Вы можете создать копию словаря, фильтруя ключи по ходу дела. Я делаю это для преобразования между верблюжьим регистром и подчеркиванием при заполнении объектов из JSON с использованием KVC. Исходный код см. в моей библиотеке рефакторинга es_ios_utils. ESNSCategories.h предоставляет:

@interface NSMutableDictionary(ESUtils)
    //Changes keys using keyFilter. If keyFilter generates duplicate non-unique keys, objects will be overwritten.
    -(void)addEntriesFromDictionary:(NSDictionary*)d withKeyFilter:(NSString*(^)(NSString*))keyFilter;
...

Итак, чтобы сделать все ключи прописными, вы можете сделать что-то вроде:

NSMutableDictionary *md = [NSMutableDictionary dictionaryWithCapacity:oldDictionary.count];
[md addEntriesFromDictionary:oldDictionary
               withKeyFilter:^NSString*(NSString *key) { 
                                 return key.uppercaseString;
                             }];
person Peter DeWeese    schedule 08.06.2011