Какова семантика использования 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), но она была закрыта как "работает как задумано". (Потому что на самом деле нет никакого способа узнать, является ли объект изменчивым или нет)