Подтвердить что ты не робот

IBOutlet и viewDidUnload под ARC

Здесь есть аналогичный вопрос на SO здесь, однако я просто хочу прояснить то, что не было полностью объяснено там.

Я понимаю, что все делегаты и торговые точки - на самом деле любая ссылка на "родительский" объект, чтобы быть хорошим гражданином и думать о графе объектов на минуту - должна обнулять слабые ссылки. Из-за характера обнуления слабых указателей, автоматически опускающихся на нуль на счету удержания объекта ссылки, достигающего нуля, означает ли это, что установка IBOutlets на nil в viewDidUnload теперь не нужна?

Итак, если я объявляю свой выход так:

@property (nonatomic, weak) IBOutlet UILabel *myLabel;

Имеет ли какой-либо эффект следующий код?

- (void)viewDidUnload
{
    self.myLabel = nil;

    [super viewDidUnload];
}
4b9b3361

Ответ 1

Просто сделайте немного исследований...

Как я понимаю, слабый аналогичен присваиванию, поскольку они оба являются слабыми ссылками.

Однако назначение не создает ссылку на обнуление. то есть, если объект, о котором идет речь, будет уничтожен, и вы получите доступ к этому свойству, вы получите BAD_ACCESS_EXCEPTION.

Слабые свойства автоматически обнуляются (= nil), когда объект, на который он ссылается, уничтожен.

В обоих случаях нет необходимости устанавливать свойство на nil, так как оно не способствует сохранению счета объекта. Это необходимо при использовании сохраняемых свойств.

По-видимому, ARC также вводит новое "сильное" свойство, которое является таким же, как "сохранить"?

Выполнено исследование здесь

Ответ 2

Я провел небольшое тестирование и оказалось, что код в методе viewDidUnload не нужен. Чтобы поддержать это, документы для viewDidUnload действительно говорят:

К моменту вызова этого метода свойство view равно nil.

Указание на то, что слабая ссылка должна быть установлена ​​на nil автоматически.

Ответ 3

У меня есть некоторые эмпирические данные, подтверждающие, что IBOutlets действительно уже установлены на nil автоматически. Вот что я сделал:

  • Я установил явные ivars для своих свойств IBOutlet (@synthesize myLabel = myLabel_), чтобы позже проверить их значения в отладчике.
  • Я включил точку останова в первой строке viewDidUnload.
  • Я организовал для viewDidUnload, чтобы получить вызов путем моделирования предупреждения о памяти.
  • Я проверил значения явных ivars, которые были связаны с моими свойствами IBOutlet.

Явные ivars все имели nil как их значение, тогда я попал в точку останова.

Ответ 4

Из моего понимания того, как управляемые точки управляются в ARC, если вы используете слабую ссылку, вам не нужно ничего добавлять в viewDidUnload, поскольку она уже будет равна нулю. Таким образом, это избыточно.

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

Ответ 5

Начиная с iOS 5 и OS X 10.7, weak создаст автоматический указатель обнуления. Это означает, что когда выделенный объект является выпуском, указатель автоматически устанавливается на nil (подробности см. В Обнуление слабых ссылок в ARC).

Итак, в iOS 5+ и OS X 10.7+ не рекомендуется устанавливать свойства weak IBOutlet в nil вручную в методе viewDidUnload: при выгрузке основного представления все его subviews будут выпущены, поэтому соответствующие свойства будут установлены на nil.