Какой метод жизненного цикла UIViewController указывает на его освобождение и помогает обнаружить утечку памяти?

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

Ответ

Это метод deinit. Он вызывается автоматически непосредственно перед освобождением экземпляра из памяти. Если deinit не вызывается — это прямой признак цикла сильных ссылок (retain cycle), ведущего к утечке памяти.

Пример утечки и ее решения:

class MyViewController: UIViewController {
    var onBackgroundChange: (() -> Void)? // Сильная ссылка на замыкание

    override func viewDidLoad() {
        super.viewDidLoad()
        // СОЗДАНИЕ ЦИКЛА (УТЕЧКА):
        // ViewController сильно ссылается на замыкание через `onBackgroundChange`,
        // а замыкание сильно ссылается на `self`.
        onBackgroundChange = {
            self.view.backgroundColor = .red // Захват `self` как strong
        }
        // РЕШЕНИЕ: Использовать weak или unowned ссылку
        onBackgroundChange = { [weak self] in
            self?.view.backgroundColor = .red
        }
    }

    deinit {
        // Этот print НЕ выполнится, если есть retain cycle.
        print("MyViewController деинициализирован")
    }
}

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

  1. Instruments → Leaks: Позволяет находить утечки в работающем приложении.
  2. Xcode Memory Graph Debugger: Визуально показывает объекты в памяти и связи между ними, мгновенно выделяя retain cycles красными значками.
  3. Встроенные счетчики ссылок в отладчике (Debug Memory Graph).