Ответ
Для сохранения контекста, связанного с UI или навигацией, используйте viewWillDisappear(_:). Для сохранения данных модели или состояния приложения — applicationWillResignActive в AppDelegate/SceneDelegate.
Почему viewWillDisappear(_:)?
Это последний гарантированный момент в жизненном цикле контроллера, когда он ещё находится в иерархии и его view видимы. Метод deinit не подходит для UI-операций, так как view к этому моменту уже удалены.
Пример сохранения навигационного состояния:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Проверяем, что контроллер действительно скрывается (а не показывается другой поверх)
if self.isMovingFromParent || self.isBeingDismissed {
// Сохраняем контекст
UserDefaults.standard.set(selectedItemId, forKey: "lastSelectedItem")
// Или передаем данные обратно через делегат/closure
delegate?.viewControllerWillClose(with: data)
}
}
Когда использовать deinit?
Только для очистки ресурсов самого контроллера (например, отписки от уведомлений, которые были добавлены в viewDidLoad). Не полагайтесь на него для сохранения данных, так как его вызов зависит от ARC и может быть отложен.
Лучшая практика: Разделяйте сохранение UI-состояния (в viewWillDisappear) и сохранение данных модели (в ответ на события жизненного цикла приложения).