#swift #xcode #viewcontroller
#swift #xcode #viewcontroller
Вопрос:
У меня есть раскадровка с двумя контроллерами просмотра. У первого, VC_1, есть одна кнопка, которая открывает 2-й — VC_2. У VC_2 также есть кнопка, которая открывает VC_1. Оба контроллера имеют почти идентичный код:
class VC_1: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
print(“VC_1 loaded")
}
override func viewDidAppear(_ animated: Bool){ print(“VC_1 appeared") }
override func viewDidDisappear(_ animated: Bool){ print(“VC_1 disappeared") }
@IBAction func btnShowVC_2(_ sender: UIButton)
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
secondVC = storyboard.instantiateViewController(identifier: “VC_2”)
secondVC.modalPresentationStyle = .fullScreen
show(secondVC, sender: self)
}
}
Разница только в «VC_2» вместо «VC_1» в коде 2-го контроллера.
Я видел этот код создания контроллера просмотра в документации Apple и во многих других примерах в Интернете.
Когда я нажимаю кнопку на VC_1, я вижу в окне отладки, что VC_2 загружается и появляется, а VC_1 исчезает. И то же самое, конечно, происходит, когда я нажимаю кнопку на VC_2 — она исчезает, и VC_1 загружается снова.
Мои вопросы:
- что происходит с объектом контроллера просмотра после вызова «viewDidDisappear»? Он действительно исчезает из памяти или «исчезает» означает только «вы не видите его на экране?». Я не вижу «viewDidUnload» в документации…
- Я полагаю, что «viewDidLoad» означает, что в памяти был создан новый объект контроллера просмотра. Есть ли какой-либо способ загрузить объект контроллера просмотра только один раз, а затем скрыть и показать его, не вызывая вызова «viewDidLoad»? Я попытался сделать это с помощью глобальной переменной «secondVC», но получил ошибку «Приложение пыталось модально представить активный контроллер».
Ответ №1:
-
viewDidDisappear: вызывается после удаления представления из иерархии представлений Windows. Нет, объект View controller просто покинул свойство view. Кстати, объем памяти, используемый контроллерами просмотра, незначителен. Так что не думайте слишком много. Если вы хотите перехватить, когда ваш объект View controller освободится из памяти, поместите
deinit { print("vc deallocated") }
-
viewDidUnload, он устарел со времен iOS 6, которая использовалась для окончательной очистки.
-
Отчасти верно. Имейте в виду, что viewDidLoad вызывается один раз для жизненного цикла контроллера просмотра. Существует метод, вызываемый перед viewdidload, но это не связано с вашим вопросом.
Комментарии:
1. Спасибо за ваш ответ. Итак, нормально ли, что каждый раз, когда я открываю полноэкранный контроллер модального просмотра с помощью перехода или из кода, вызывается «viewDidLoad» (с большим количеством кода)? Я хочу точно понять — если открывается контроллер просмотра, а затем открывается другой полноэкранный режим, существует ли первый в памяти (пока он не виден на экране)? Если да, то почему система вызывает «viewDidLoad» при следующем открытии первого контроллера просмотра? Если нет… ну, хорошо.
2. (Все мои вопросы и возможные недоразумения связаны с программированием MS Windows — окна в Windows наверняка существуют, даже когда они невидимы, а WM_CREATE действительно вызывается только один раз 🙂
3. нет, это логичные вопросы 🙂 например, если вы используете навигационный контроллер и переходите с vc1 на vc2, и когда вы видите vc2, vc1 не будет в памяти. не могли бы вы принять мой ответ и проголосовать, если не возражаете 🙂
Ответ №2:
В дополнение к «Существует метод перед viewdidload» -> loadView( )
это метод, управляемый ViewController. ViewController вызывает его, когда его текущее представление равно нулю. loadView () в основном принимает представление (которое вы создаете) и устанавливает его в ViewController view (superview).