Может ли метод viewDidLoad быть вызван дважды у UIViewController
Что проверяют
Понимаете ли вы, что viewDidLoad привязан не к экземпляру контроллера и не к показу экрана, а к загрузке его view. Вопрос с подвохом: правильный ответ не «да» и не «нет», а разбор того, что считать повторным вызовом. Следом спрашивают, куда класть код, который выполняется при каждом появлении экрана.
Как отвечать
- правило: свойство
viewуUIViewControllerленивое. При первом обращении к нему вызываетсяloadView(из сториборда,.xibили руками), сразу за нимviewDidLoad. У одного экземпляра при обычной работе это происходит ровно один раз; - возврат по навигации не считается:
popViewControllerвозвращает к экземпляру, у которого представление уже загружено. СработаютviewWillAppearиviewDidAppear, но неviewDidLoad; - новый экземпляр это новый вызов: каждый
instantiateViewControllerсоздаёт свой объект со своим жизненным циклом. Экран, открытый дважды, это два вызова у разных контроллеров, а не повторный вызов у одного; - как получить второй вызов у одного объекта: обнулить представление,
controller.view = nil. Следующее обращение кviewснова пройдётloadViewиviewDidLoad; - историческая часть: до iOS 6 система выгружала невидимые представления при нехватке памяти и звала
viewDidUnload, после чегоviewDidLoadвызывался заново. Метод давно устарел, автоматической выгрузки нет, но легенда тянется оттуда.
Практический вывод: в viewDidLoad разовая настройка (иерархия вью, констрейнты, подписки), в viewWillAppear то, что обновляется при каждом показе. Состояние проверяют через isViewLoaded, грузят принудительно через loadViewIfNeeded().
Где спотыкаются
Уверенно отвечают «да, при нехватке памяти», не зная, что это про iOS 5. Сейчас didReceiveMemoryWarning представление не выгружает.
Трогают view слишком рано, в инициализаторе или в prepare(for:sender:), чтобы «положить текст в лейбл». Это принудительно грузит представление и ломает порядок событий: данные кладут в свойства и применяют в viewDidLoad.
Кладут в viewDidLoad загрузку данных и потом удивляются, что при возврате на экран они устарели. Обновление это viewWillAppear или подписка на изменения модели.