> Что такое утечки памяти и когда они гарантированно возникают? (iOS, Swift)
Уровень: junior · Роль: mobile · Категория: Технические вопросы
Компании: Eltex
Стек: iOS, Swift
> Пример ответа
Короткий ответ
Утечка памяти - это ситуация, когда объект продолжает занимать память, хотя он больше не нужен приложению. В Swift с ARC утечки гарантированно возникают при наличии сильных ссылочных циклов (retain cycles) между классами, особенно с замыканиями, делегатами или таймерами. Также утечки возможны при неправильном использовании глобальных переменных, статических свойств или захвате self в замыканиях без [weak self].
Подробное объяснение
В Swift управление памятью основано на автоматическом подсчёте ссылок (ARC). Каждый объект класса имеет счётчик сильных ссылок. Когда счётчик падает до нуля, память освобождается. Утечка возникает, когда счётчик никогда не достигает нуля, хотя объект логически больше не нужен.
Гарантированные утечки возникают при:
-
Retain cycle между двумя объектами - например, класс A сильно ссылается на класс B, а класс B сильно ссылается на класс A. Оба объекта остаются в памяти навсегда.
-
Замыкания, захватывающие
self- если замыкание хранится как свойство объекта и внутри захватываетselfсильно, возникает цикл: объект → замыкание → объект. -
Таймеры и делегаты -
Timerс повторением, который сильно удерживает target, или делегат, объявленный какstrong, вместоweak. -
Глобальные или статические хранилища - если объект помещается в глобальный массив или статическое свойство, он живёт всё время жизни приложения.
Важно понимать: ARC не убирает утечки автоматически. Он лишь гарантирует, что память освободится, когда сильных ссылок не останется. Задача разработчика - правильно проектировать граф ссылок.
На практике
На iOS утечки чаще всего проявляются в:
- UIViewController - если контроллер захвачен замыканием или таймером, он не вызывается в
deinit, и экран "зависает" в памяти при навигации. - Сетевые запросы - completion handler, который сильно захватывает
self, удерживает контроллер до завершения запроса. - Наблюдатели и NotificationCenter - если не удалить наблюдателя в
deinit, объект может остаться в памяти. - Core Animation и CADisplayLink - циклы с сильными ссылками на target.
Диагностика: инструмент Instruments (Leaks и Allocations), проверка deinit через логи, использование weak и unowned в замыканиях.
Пример кода
SWIFT// Пример утечки через retain cycleclass ProfileViewController: UIViewController {var onSave: (() -> Void)?func setup() {// Утечка: замыкание захватывает self сильноonSave = {self.saveProfile()}}func saveProfile() {// ...}deinit {print("ProfileViewController deallocated")}}// Исправлениеfunc setup() {onSave = { [weak self] inself?.saveProfile()}}// Пример утечки через таймерclass TimerViewController: UIViewController {var timer: Timer?override func viewDidLoad() {super.viewDidLoad()// Утечка: таймер сильно удерживает selftimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ inself?.updateUI()}}deinit {timer?.invalidate()print("TimerViewController deallocated")}}
Как отвечать на собеседовании
Начни с определения утечки и роли ARC. Затем перечисли основные сценарии гарантированных утечек: retain cycle, замыкания с self, таймеры, глобальные хранилища. Обязательно упомяни, что weak и unowned - основные инструменты для разрыва циклов. Приведи пример из практики: контроллер, который не освобождается после pop. Покажи, как проверить утечку через deinit или Instruments. Для junior достаточно уверенно объяснить базовые случаи и способы исправления.
Что проверяет интервьюер
Интервьюер оценивает:
- Понимание ARC и разницы между
strong,weak,unowned. - Умение находить retain cycle в коде.
- Знание типичных мест утечек в iOS: замыкания, делегаты, таймеры, NotificationCenter.
- Практические навыки: как диагностировать и исправлять.
- Понимание, что
unownedопасен, если объект может статьnil, и лучше использоватьweak.
Типичные ошибки
- Путаница между
weakиunowned-unownedпредполагает, что объект живёт дольше, иначе будет crash. - Забывают про
[weak self]в замыканиях, которые хранятся как свойства. - Не вызывают
invalidate()у таймера или не удаляют наблюдателей. - Считают, что value types (struct) не могут вызывать утечки - это верно, но они могут содержать классы.
- Не проверяют
deinitпри тестировании - утечка остаётся незамеченной. - Используют
weakдля замыканий, когда нужноunowned, или наоборот, без понимания жизненного цикла.
> Похожие задачи по mobile
Помнишь названия команд или проектов, с которыми работал?
Зачем в бизнес-логике используются слабые ссылки в Swift?
Какой жизненный цикл у ячейки в списке в iOS?
Были ли реджекты приложений из-за скрытого функционала или дизайна?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью