Когда создается корневое view (view) у UIViewController?

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

Ответ

Корневое view (свойство view) создаётся лениво, в момент первого к нему обращения. Система управляет этим процессом через механизм Lifecycle Load.

Процесс загрузки view:

  1. При первом обращении к свойству view (например, в коде или при добавлении контроллера в иерархию), если оно nil, вызывается метод loadView().
  2. Метод loadView():
    • Ответственен за создание и присвоение корневого view свойству view.
    • По умолчанию он создаёт пустое UIView, если nibName не указан.
    • Переопределять его нужно осторожно, только для создания view программно, не вызывая super.loadView() (если создаёте view вручную).
  3. Сразу после loadView() вызывается viewDidLoad() — здесь view гарантированно загружена и готова для начальной настройки.

Практические следствия и примеры:

  • Опасный код (краш): Обращение к view до её загрузки, например, в инициализаторе.

    class MyVC: UIViewController {
        init() {
            super.init(nibName: nil, bundle: nil)
            view.backgroundColor = .red // CRASH! `view` is nil.
        }
    }
  • Безопасный код: Вся работа с иерархией view должна быть в viewDidLoad() или позже.

    class MyVC: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            // `view` здесь уже создана и безопасна для использования.
            view.backgroundColor = .white
            setupSubviews()
        }
    }
  • Принудительная загрузка: Если необходимо получить доступ к view до её показа (редкий кейс), можно использовать loadViewIfNeeded() (iOS 9+).

    let vc = MyVC()
    vc.loadViewIfNeeded() // View создана, viewDidLoad вызван.
    print(vc.view.frame) // Безопасно.