Все объекты, используемые в качестве ключей в NS (Изменяемые) Словари должны поддерживать протокол NSCopying и те объекты, копируются, когда они используются в словаре.
Я часто хочу использовать более тяжелые объекты веса в качестве ключей, просто отобразить один объект на другого. Что я действительно имею в виду, когда я делаю, который является эффективно:
[dictionary setObject:someObject forKey:[NSValue valueWithPointer:keyObject]];
("Когда я возвращаюсь и вручаю Вам этот тот же экземпляр ключевого объекта снова, получаю меня то же самое значение".)
... который является точно, что я заканчиваю тем, что делал для обхождения этого дизайна иногда. (Да, я знаю о NSMapTable в настольном Какао; но например, iPhone не поддерживает это.)
Но то, что я действительно не получаю, - то, почему копирование ключа необходимо или желательно во-первых. Что это покупает реализацию или вызывающую сторону?
Копия гарантирует, что значения, используемые в качестве ключей, не изменятся «скрытно» при использовании в качестве ключей. Рассмотрим пример изменяемой строки:
NSMutableString* key = ...
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[dict setObject: ... forKey: key];
Предположим, что словарь не копировал ключ, а просто сохранил
его. Если сейчас, в более поздний момент, исходная строка будет изменена, то весьма вероятно, что вы больше не найдете свое сохраненное значение в словаре, даже если вы используете тот же самый ключевой объект (т. Е. Тот ключ
указывает на в примере выше).
Чтобы обезопасить себя от такой ошибки, словарь копирует все ключи.
Кстати, обратите внимание, что достаточно просто определить -copyWithZone:
как просто выполнение return [self keep]
. Это разрешенный и хороший код, если ваш объект неизменен, а контракт NSCopying
специально разработан таким образом, что возвращаемый объект должен быть (вроде, вроде) неизменным:
Реализуйте NSCopying, сохранив вместо этого оригинал создания новой копии, когда класс и его содержимое неизменны.
(из Ссылка NSCopying )
и
Возвращенная копия является неизменной, если к принимающему объекту применяется соображение «неизменяемый против изменяемого»; в противном случае точный характер копии определяется классом.
(из -copyWithZone: Ссылка )
Даже если ваши объекты не являются неизменяемыми, вам может сойти с рук эта реализация, если вы когда-либо будете использовать только реализации равенства / хеширования на основе идентичности, т. Е. Реализации на которые никак не влияет внутреннее состояние объекта.