Разница между viewDidLoad и viewDidAppear

86

В чем разница между viewDidLoadи viewDidAppear? Какого рода инициализация или специальный код входит в эти функции?

например, presentModalViewControllerработает только когда присутствует, viewDidAppearа не включен viewDidLoad.

user462455
источник

Ответы:

147

viewDidLoadвызывается ровно один раз, когда контроллер представления впервые загружается в память. Здесь вы хотите создать экземпляры любых переменных экземпляра и построить любые представления, которые существуют на протяжении всего жизненного цикла этого контроллера представления. Однако вид на этом этапе обычно еще не виден.

viewDidAppearвызывается, когда представление действительно отображается, и может вызываться несколько раз в течение жизненного цикла контроллера представления (например, когда модальный контроллер представления закрывается и представление снова становится видимым). Здесь вы хотите выполнять любые действия с макетом или рисовать в пользовательском интерфейсе - например, представлять контроллер модального представления. Однако все, что вы здесь делаете, должно повторяться. Лучше не сохранять вещи здесь, иначе вы получите утечки памяти, если не отпустите их, когда представление исчезнет.

См. Https://developer.apple.com/documentation/uikit/uiviewcontroller.

Давидголи
источник
15
Вы и WrightsCS абсолютно правы. Но не для секущихся волос, а хотя viewDidLoadобычно вызывается только один раз, есть одна ситуация, когда его можно вызвать снова. В частности, если вы когда-либо получите a didReceiveMemoryWarning, ваши невидимые представления могут быть освобождены (хотя контроллеры представлений остаются нетронутыми) и, когда вы вернетесь обратно, viewDidLoadмогут быть вызваны для них снова.
Роб
1
Я не уверен, согласен ли я с комментарием о том, что ivars контроллера представления всегда и автоматически выпускаются для вас (сам контроллер не выпускается). Я подозреваю, что мы оба могли бы легко создать viewDidLoad, который вылился бы в утечку, если бы его повторно вызывали после didReceiveMemoryWarning. Но я согласен с тем, что если вы будете использовать передовой опыт при написании своего viewDidLoad, все будет в порядке. Единственное, что я хочу сказать, это то, что небрежное использование ivars и ручное управление памятью может определенно привести к утечкам viewDidLoad. Люди должны быть внимательны к didReceiveMemoryWarningсценарию и соответственно программировать.
Роб
2
Не вдаваясь в подробности, но менее чем через 24 часа после этого обмена, отвечая на другой вопрос , я нашел пример именно того viewDidLoadкода, который может просочиться didReceiveMemoryWarning. Вздох.
Роб
1
Этот ответ прямо противоречит другому: stackoverflow.com/a/3411636/269753 Я наблюдал, как мой метод viewDidLoad вызывался более одного раза, даже когда я вообще не получал предупреждений о памяти. Кто-нибудь хочет уточнить?
Рикардо Санчес-Саез
2
Не вижу противоречия. Этот вопрос касается отношения между viewDidLoad и viewDidUnload, а не viewDidAppear.
Давидголи
21

Проще говоря, вам нужно создать какие-либо элементы управления или массивы viewDidLoad, где, как и в viewDidAppearэтом случае, вы хотите обновить эти элементы управления или массивы.

viewDidLoadвызывается один раз при создании контроллера и viewDidAppearвызывается каждый раз при появлении представления, ну, DID. Скажем, у вас есть модальное представление, которое вы представляете, когда это представление отклоняется, оно viewDidAppearбудет вызываться и viewDidLoadне будет вызываться.

WrightsCS
источник
3
Первый абзац - это хороший совет. Но второй абзац неверен. viewDidLoadможет вызываться более одного раза . Если ваше представление, пока оно не отображается (в стеке других представлений), выгружается более старыми версиями iOS в ситуации нехватки памяти, то контроллер представления автоматически перезагружает представление при необходимости его повторного отображения на экране. В более поздних версиях iOS вы можете уменьшить использование памяти, сделав то, что делала для вас более ранняя версия iOS: выгружать закадровые представления при получении didReceiveMemoryWarningсообщения, и в этом случае viewDidLoadфункция будет вызываться снова.
Basil Bourque
@WrightsCS есть ли у вас официальный документ по Apple, в котором это сказано? «viewDidLoad вызывается один раз при создании контроллера» Потому что я помню, что раньше viewDidLoad можно было вызывать несколько раз в сценариях с нехваткой памяти. Большое спасибо.
Рикардо