Ответ вслух Middle ARC и циклы ссылок спрашивают часто обновлено

Циклы ссылок в iOS: где возникают и как найти

Вопрос

Где на практике возникают циклы сильных ссылок и как вы их находите и исправляете?

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

ARC считает только сильные ссылки и не умеет освобождать циклы: если A держит B, а B держит A, их счётчики никогда не станут нулём.

Что должно прозвучать в ответе

  • ARC не собирает циклы, `deinit` не вызывается

  • Источники: делегаты, замыкания в свойствах, таймеры, наблюдатели, подписки Combine

  • Лечение: `weak` для обратных ссылок, `[weak self]` в escaping-замыканиях, `invalidate`/отписка

  • Поиск: Memory Graph Debugger, Instruments, лог в `deinit`

  • Тест на утечку: слабая ссылка на объект после теста должна стать `nil`

Что могут спросить следом

  • Почему UIView.animate не создаёт цикл?
  • Как подписка sink в Combine приводит к утечке?

Разбор

ARC считает только сильные ссылки и не умеет освобождать циклы: если A держит B, а B держит A, их счётчики никогда не станут нулём. На практике это делегат, объявленный сильным, замыкание в свойстве, которое захватывает self, таймер с target, блочный наблюдатель NotificationCenter, подписка Combine, сохранённая в cancellables самого объекта, с sink { self... }. Лечу так: обратные ссылки weak, в escaping-замыканиях [weak self] и guard let self, таймеры инвалидирую, подписки отменяю. Нахожу через Memory Graph Debugger: открываю и закрываю экран несколько раз и смотрю, сколько живых контроллеров. Для критичных экранов пишу тест: держу слабую ссылку на view model и проверяю в teardown, что она стала nil.

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

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