Выбор ответа Middle ARC и циклы ссылок обновлено

Почему Timer держит контроллер

Вопрос

Контроллер создаёт Timer.scheduledTimer(timeInterval:target: self, selector:..., repeats: true) и инвалидирует таймер в deinit. Почему deinit никогда не вызывается?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Таймер сильно держит target, а run loop держит таймер. Run loop удерживает запланированный таймер, а таймер с target-action сильно удерживает target.

Варианты ответа

  1. deinit у контроллеров не вызывается, их освобождает UIKit по-своему
  2. Таймер сильно держит target, а run loop держит таймерправильный ответ
  3. Таймер держит контроллер слабо, а проблема в неверном селекторе
  4. Повторяющиеся таймеры сами инвалидируются в deinit, и он зацикливается

Разбор

Run loop удерживает запланированный таймер, а таймер с target-action сильно удерживает target. Инвалидация в deinit это замкнутый круг: deinit не наступит, пока таймер жив. Правильно: инвалидировать в viewWillDisappear или использовать блочный API с [weak self] и инвалидировать в deinit. У контроллеров deinit вызывается нормально, если нет лишних ссылок.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.