Что такое memory leak в iOS и как с ним работать?

«Что такое memory leak в iOS и как с ним работать?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Memory leak (утечка памяти) — ситуация, когда объект больше не нужен, но не освобождается сборщиком мусора из-за сохранённых сильных ссылок. В Swift/Objective-C это часто происходит из-за retain cycles.

Основные причины:

  1. Retain cycles в замыканиях — когда замыкание захватывает self без weak/unowned.
  2. Сильные ссылки в делегатах — использование strong вместо weak для делегатов.
  3. Неосвобождаемые ресурсы — таймеры, наблюдатели (observers), уведомления (notifications).

Пример retain cycle:

class ViewController: UIViewController {
    var closure: (() -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()
        // ПРОБЛЕМА: сильная ссылка на self → retain cycle
        closure = { 
            self.doSomething()
        }
    }
}

Решение:

// 1. Используйте weak ссылку
closure = { [weak self] in
    self?.doSomething()
}

// 2. Или unowned (если self гарантированно существует)
closure = { [unowned self] in
    self.doSomething()
}

Инструменты для поиска утечек:

  • Instruments → Leaks/Allocations — профилирование памяти в реальном времени
  • Debug Memory Graph в Xcode — визуализация графа объектов
  • Address Sanitizer — обнаружение ошибок работы с памятью

Best practices:

  • Всегда используйте weak для делегатов и протоколов
  • Освобождайте ресурсы в deinit (таймеры, наблюдатели)
  • Проверяйте retain cycles при использовании замыканий