> Какой жизненный цикл у UIViewController и в каком порядке вызываются методы (iOS, Swift)
Уровень: senior · Роль: mobile · Категория: Технические вопросы
Компании: VK, Физтех-Центр, Bip.ru, Doubletapp, Битрикс24, Совкомбанк, Яндекс
Стек: iOS, Swift
> Пример ответа
Короткий ответ
Жизненный цикл UIViewController - это последовательность вызовов методов, отражающих переходы между состояниями: загрузка view, появление на экране, исчезновение, освобождение памяти. Основной порядок: loadView → viewDidLoad → viewWillAppear → viewDidAppear → viewWillDisappear → viewDidDisappear. При нехватке памяти вызывается didReceiveMemoryWarning. Методы вызываются в строгом порядке, но некоторые могут повторяться при повторном появлении контроллера.
Подробное объяснение
Жизненный цикл делится на две фазы: создание и отображение view, а также управление памятью.
Фаза создания view:
loadView- создаёт корневую view контроллера. Вызывается один раз при первом обращении кview. Если переопределён, нужно создать view вручную и присвоить вself.view. Если не переопределён, загружается из storyboard/xib или создаётся пустая UIView.viewDidLoad- вызывается сразу после загрузки view в память. Здесь выполняют начальную настройку: конфигурация UI-элементов, подписки, начальные данные. Вызывается один раз за время жизни контроллера.
Фаза появления/исчезновения:
viewWillAppear(_:)- вызывается перед добавлением view в иерархию окон. Используется для обновления данных, скрытия/показа элементов, настройки navigation bar.viewDidAppear(_:)- вызывается после полного отображения view на экране. Подходит для запуска анимаций, аналитики, тяжёлых операций.viewWillDisappear(_:)- вызывается перед удалением view с экрана. Используется для отмены операций, сохранения состояния, снятия подписок.viewDidDisappear(_:)- вызывается после полного исчезновения view. Здесь можно освобождать ресурсы, останавливать анимации.
Управление памятью:
didReceiveMemoryWarning- вызывается при нехватке памяти. Нужно освобождать кэши, пересоздаваемые ресурсы.deinit- вызывается при уничтожении контроллера. Освобождение всех ресурсов, отписка от NotificationCenter.
Важные нюансы:
- Порядок вызовов при первом показе:
loadView→viewDidLoad→viewWillAppear→viewDidAppear. - При повторном показе (например, после dismiss или pop):
viewWillAppear→viewDidAppear- без повторногоviewDidLoad. - При переходе на другой контроллер (push/present): сначала вызываются
viewWillDisappearиviewDidDisappearтекущего, затемviewWillAppearиviewDidAppearнового. viewDidLoadне гарантирует, что view уже на экране - только что загружена в память.- В iOS 13+ при свайпе назад с edge-swipe порядок может быть:
viewWillDisappear→viewWillAppear(если жест отменён) →viewDidAppear.
На практике
Для senior-позиции важно не просто перечислить методы, а показать понимание, когда что использовать и какие подводные камни бывают.
Типичные сценарии:
- viewDidLoad - настройка один раз: создание элементов, начальные значения, подписки на Combine/NotificationCenter.
- viewWillAppear - обновление данных при каждом показе: перезагрузка таблицы, обновление UI из модели, изменение title.
- viewDidAppear - старт анимаций, отправка аналитики, показ onboarding.
- viewWillDisappear - отмена сетевых запросов, сохранение черновиков, скрытие клавиатуры.
- viewDidDisappear - остановка анимаций, освобождение тяжёлых ресурсов (например, видео).
Практические рекомендации:
- Не выполняйте тяжёлые операции в
viewDidLoad- это замедлит первый показ. - Используйте
viewWillAppearдля обновления данных, если они могли измениться на предыдущем экране. - При работе с NotificationCenter подписывайтесь в
viewWillAppearи отписывайтесь вviewWillDisappear, чтобы избежать утечек при переходах. - Для кэшируемых данных используйте
didReceiveMemoryWarningдля очистки. - Внимательно с порядком при модальных презентациях:
viewWillDisappearвызывается у presenting контроллера, ноviewDidDisappear- только после завершения анимации.
Пример кода
SWIFTfinal class ProfileViewController: UIViewController {private let networkService = NetworkService()private var data: [String] = []override func loadView() {super.loadView()// Если нужно создать view вручную// view = CustomView(frame: UIScreen.main.bounds)}override func viewDidLoad() {super.viewDidLoad()setupUI()configureNavigationBar()// Начальная загрузка данных - но не тяжёлая}override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)// Обновляем данные при каждом показеrefreshData()// Подписка на уведомленияNotificationCenter.default.addObserver(self,selector: #selector(handleNotification),name: .someNotification,object: nil)}override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)// АналитикаAnalytics.trackScreen("Profile")// Старт анимацииstartLoadingAnimation()}override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)// Отписка от уведомленийNotificationCenter.default.removeObserver(self)// Сохранение состоянияsaveDraft()}override func viewDidDisappear(_ animated: Bool) {super.viewDidDisappear(animated)// Остановка анимацииstopLoadingAnimation()}override func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()// Очистка кэшаimageCache.removeAll()}deinit {// Полная очисткаnetworkService.cancelAllRequests()}}
Как отвечать на собеседовании
Начните с краткого перечисления методов в правильном порядке, затем переходите к деталям. Покажите понимание, что viewDidLoad - одноразовый, а viewWillAppear/viewDidAppear - повторяемые. Обязательно упомяните loadView и didReceiveMemoryWarning - это отличает senior от junior.
Хорошая структура ответа:
- Перечислите методы в порядке вызова.
- Объясните, что происходит на каждом этапе.
- Приведите пример, когда что использовать.
- Упомяните edge case: повторный показ, модальные переходы, обработка памяти.
Если спросят про конкретный сценарий (например, "что будет при push нового контроллера"), опишите порядок вызовов для обоих контроллеров.
Что проверяет интервьюер
- Понимание разницы между одноразовыми и повторяемыми вызовами.
- Знание
loadViewи когда его переопределяют. - Понимание управления памятью:
didReceiveMemoryWarning,deinit. - Умение применять методы на практике: где подписываться, где отписываться.
- Осознание порядка вызовов при переходах между контроллерами.
- Понимание, что
viewDidLoadне означает, что view на экране.
Типичные ошибки
- Путаница между
viewDidLoadиviewWillAppear- кандидат не понимает, что первый вызывается один раз. - Забывают про
loadViewили не могут объяснить, зачем он нужен. - Не упоминают
didReceiveMemoryWarning- для senior это критично. - Подписываются на NotificationCenter в
viewDidLoadи не отписываются - утечка памяти. - Выполняют тяжёлые операции в
viewDidLoad, замедляя первый показ. - Не знают порядок вызовов при модальных переходах или edge-swipe.
- Говорят, что
viewDidLoadвызывается при каждом показе - грубая ошибка.
> Похожие задачи по mobile
Ты сейчас в активном поиске работы
В чем разница между weak и unowned ссылками в Swift и когда их использовать
Какие паттерны проектирования вы знаете и использовали в работе
Какую архитектуру вы бы выбрали для годового проекта
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью