ПРИМЕЧАНИЕ. Это было связано с ошибкой в некоторых бета-версиях XCode, которые уже давно исправлены. Этот вопрос и ответ, вероятно, не помогут вам, если у вас возникнут проблемы с ARC.
Я переношу свой проект с ручного подсчета ссылок на ARC и наткнулся на проблему: Как я могу гарантировать, что пользовательский установщик для свойства сохранения действительно сохраняет?
В myClass.h
я объявил свойство: @property (retain) NSDate *date
. Неважно, вручную ли я устанавливал __strong
ivar или автогенерировал.
В реализации я, конечно, @synthesize date
, и внедрил настраиваемый наборщик (или просто скачать демонстрационный проект Xcode):
- (void)setDate:(NSDate *)newDate
{
if (allowedToSetNewDate)
{
date = newDate;
}
}
Это, похоже, не сохраняет дату и дает мне message sent to deallocated instance
, когда newName (автоматически) освобождается там, откуда он появился, при попытке получить доступ к myClass.date
позже (при условии, что Zombie включен, в противном случае он просто падает тихо).
Изменение настройки, используемой date = [newDate copy]
, работает вокруг ошибки, но на самом деле я этого не хочу. Удаление пользовательского сеттера также работает, но явно нежелательно.
Что мне здесь не хватает? Как я могу гарантировать, что пользовательский сеттер для сохраняемого свойства фактически сохраняется в среде ARC? Это кажется такой основной и общей задачей, что я думаю, что я пропускаю что-то очень очевидное.
(ПРИМЕЧАНИЕ. Это не подпадает под условия любой Apple NDA, поскольку ARC публично выпущена как часть LLVM)
EDIT: Я создал небольшой проект Xcode для демонстрации проблемы и загрузки ее в github. Не стесняйтесь загрузить его и поиграть. Я нахожусь в своем уме (хотя мой остроумие сегодня не в лучшем состоянии, по общему признанию).
EDIT: для этого типового проекта эта проблема решена (см. принятый ответ). К сожалению, в более крупном проекте, на который я не могу поделиться, проблема сохраняется. В качестве обходного пути я добавил дублирующие свойства strong
с синтезированными сеттерами (ivars не работает). Новый пользовательский сеттер теперь выглядит следующим образом:
- (void)setDate:(NSDate *)newDate
{
if (allowedToSetNewDate)
{
self.date_arcretain = newDate; //this property is only there as a workaround. ARC properly retains it, but only if the setter is synthesized
date = newDate;
}
}