Когда и как выделяется память для root view у UIViewController?

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

Ответ

Память для корневого представления (view) выделяется лениво (lazy) при первом обращении к свойству view контроллера, но до его отображения на экране.

Последовательность инициализации:

  1. Инициализация контроллера: init(nibName:bundle:) или init(coder:). Представление еще не создано.
  2. Первый доступ к view: Система проверяет, загружено ли представление. Если нет — вызывает метод loadView().
  3. Метод loadView():
    • Если вы переопределили его и создали представление вручную, оно присваивается свойству view.
    • Если нет, система пытается загрузить его из storyboard или xib-файла.
    • Если и это не удалось, создается пустой объект UIView.
  4. Вызов viewDidLoad(): Сразу после загрузки представления и выделения памяти. Здесь можно выполнять дополнительную настройку.

Пример, демонстрирующий ленивую загрузку:

class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        print("View loaded and memory allocated.")
    }
}

let vc = MyViewController()
print("Controller created. View is nil? (vc.viewIfLoaded == nil)") // true

// Память выделяется здесь:
_ = vc.view // Триггерит loadView() -> viewDidLoad()
print("View accessed. View is nil? (vc.viewIfLoaded == nil)") // false

Важно: Не обращайтесь к view контроллера до его загрузки (например, в init), это приведет к преждевременной загрузке.