Какова семантика использования retain vs. copy для свойства типа NSMutableSet;

Я использую самый превосходный Accessorizer для автоматического создания сеттеров / получателей для моего кода Obj-C в Xcode. Недавно в Accessorizer было внесено изменение:

старая версия Accessorizer:
@property (nonatomic, retain) NSMutableSet * setA;
@property (nonatomic, retain) NSMutableSet * setB;

Новая версия Accessorizer:
@property (nonatomic, copy) NSMutableSet * setA;
@property (nonatomic, copy) NSMutableSet * setB;

К сожалению, новая версия ломает мой код. В моем коде я делаю следующее:

self.setA = [[[NSMutableSet alloc] init] autorelease];
self.setB = [[[NSMutableSet alloc] init] autorelease];

//...

[self.setA minusSet:self.setB];  

Приведенная выше строка кода работает нормально, используя старый способ (сохранить), но вылетает, используя новый способ (копия). Очевидно, что-то здесь не так. Я очень полагаюсь на Accessorizer. Может ли кто-нибудь уточнить последствия использования копирования / сохранения в контексте NSMutableSet?

Спасибо,
Doug

2 ответа

Решение

Если ваш тип свойства является изменяемым набором, вы, скорее всего, захотите сохранить. Если это не изменяемый набор (он же NSSet), в рекомендациях Apple говорится, что следует использовать копирование, а не сохранение.

Различие состоит в том, что существует ожидание того, что изменчивый набор изменится. Ожидается, что неизменяемый набор останется неизменным, но если он объявлен как сохраняющий, кто-то может установить его в изменяемый набор, а затем неожиданно изменить его содержимое.

Да, это "особенность" свойств. Когда вы устанавливаете свойство, которое объявлено как copyтогда сгенерированный сеттер будет вызывать -copy на объекте. К сожалению, в случае изменяемых объектов это приводит к неизменному варианту.

Другими словами, объект, возвращаемый [myMutableSet copy] не является изменчивым

Если вам нужно, чтобы набор был изменяемым, то вы должны использовать retain (или переопределите установщик для использования mutableCopy вместо copy).

Я подал ошибку в этом (rdar://8416047), но она была закрыта как "работает как задумано". (Потому что на самом деле нет никакого способа узнать, является ли объект изменчивым или нет)

Другие вопросы по тегам