ПРИМЕЧАНИЕ: Это произошло из-за ошибки в некоторых бета-версиях XCode, которая уже давно исправлена. Этот вопрос и ответ, вероятно, не помогут вам, если у вас возникнут проблемы с ARC.
Я переношу свой проект с ручного подсчета ссылок на ARC и наткнулся на проблему: Как я могу гарантировать, что пользовательский установщик для действительно ли сохраняется свойство?
В
myClass.h
я объявил свойство:@property (сохранить) NSDate * date
. Не имеет значения, установил ли я вручную__ strong
ivar или автоматически сгенерировал его.В реализации я, конечно, использовал
@synthesize date
и реализовал настраиваемый установщик ( или просто загрузите демонстрационный проект Xcode ):- (void)setDate:(NSDate *)newDate { if (allowedToSetNewDate) { date = newDate; } }
Кажется, это не сохраняет дату и дает мне
сообщение, отправленное в освобожденный экземпляр
, когда newName (автоматически) выпущено, где он появился при попытке доступа кmyClass.date
позже (при условии, что Zombie включен; в противном случае он просто вылетает без звука).Изменение установщика на использование
date = [newDate copy]
работает вокруг ошибки, но это не совсем то, что мне нужно. Удаление пользовательского установщика также работает, но, очевидно, нежелательно.Что мне здесь не хватает? Как я могу гарантировать, что пользовательский установщик для свойства сохранения действительно сохраняется в среде ARC? Это кажется такой простой и распространенной задачей, что я думаю, что упускаю из виду кое-что очень очевидное.
(ПРИМЕЧАНИЕ: это не подпадает под условия соглашения о неразглашении информации Apple, поскольку ARC публикуется как часть LLVM)
РЕДАКТИРОВАТЬ: Я создал небольшой проект Xcode, чтобы продемонстрировать проблему, и загрузил его в github. Не стесняйтесь загрузить его и поэкспериментировать. Я на грани своего остроумия (хотя, по общему признанию, мой остроумие сегодня не в лучшем виде).
РЕДАКТИРОВАТЬ: В этом примере проекта эта проблема решена (см. Принятый ответ). К сожалению, в более крупном проекте, которым я не вправе делиться, проблема сохраняется. В качестве обходного пути я добавил повторяющиеся
сильные
свойства с синтезированными сеттерами (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; } }