Вопрос проверяет понимание ленивой загрузки view, управления памятью и реальных сценариев, где жизненный цикл ведёт себя не так, как ожидают новички.
viewDidLoad вызывается один раз, потому что view загружается лениво и живёт в памяти, пока контроллер существует. Повторный вызов возможен, если view была выгружена из памяти и затем создана заново. Такое может происходить при нехватке памяти или при ручном обнулении view. В обычных сценариях это редкость, но учитывать это всё равно важно.
Метод viewDidLoad тесно связан с моментом создания view, а не с её показом на экране. Именно это объясняет, почему он почти всегда вызывается один раз.
UIKit использует ленивую загрузку:
view создаётся только при первом обращении
после загрузки view хранится в памяти
повторный показ экрана не пересоздаёт view
Пока view существует, viewDidLoad больше не вызывается.
Повторный вызов возможен, если view была уничтожена.
Системная выгрузка памяти
при сильном memory pressure
система может выгрузить view, оставив UIViewController
Ручное обнуление view
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
view = nil
}
Некорректное управление жизненным циклом
кастомные контейнеры
неправильное использование child view controllers
UIKit не гарантирует, что view будет выгружена или пересоздана. Код должен быть корректным независимо от того, вызовется ли viewDidLoad повторно.
viewDidLoad — это точка инициализации view, а не экранной логики. Повторный вызов возможен, но проектировать код, рассчитывая на него, — ошибка.