Глядя, чтобы понять жизненный цикл iOS UIViewController

не могли бы вы объяснить мне правильно управлять UIViewController жизненный цикл?

в частности, я хотел бы знать, как использовать Initialize, ViewDidLoad, ViewWillAppear, ViewDidAppear, ViewWillDisappear, ViewDidDisappear, ViewDidUnload и Dispose методы в Mono Touch для UIViewController класса.

12 ответов


все эти команды вызываются автоматически в соответствующее время iOS при загрузке/представлении / скрытии контроллера вида. Важно отметить, что эти методы прикреплены к UIViewController, а не UIViews себя. Вы не получите ни одной из этих функций, просто используя UIView.

на сайте Apple есть отличная документация здесь. Говоря просто, хотя:

  • ViewDidLoad - вызывается при создании класса и нагрузки из xib. Отлично подходит для первоначальной настройки и одноразовой работы.

  • ViewWillAppear - вызывается прямо перед отображением вашего вида, хорошо для скрытия / отображения полей или любых операций, которые вы хотите выполнить каждый раз, прежде чем вид будет виден. Поскольку вы можете перемещаться между видами, это будет вызываться каждый раз, когда ваш вид появится на экране.

  • ViewDidAppear - вызывается после появления вида-отличное место для начала анимация или загрузка внешних данных из API.

  • ViewWillDisappear/DidDisappear - та же идея, что и ViewWillAppear/ViewDidAppear.

  • ViewDidUnload/ViewDidDispose - в Objective C, это где вы делаете очистку и выпуск вещей, но это обрабатывается автоматически, так что не так много вам действительно нужно сделать здесь.


жизненный цикл UIViewController показан здесь:

http://rdkw.wordpress.com/2013/02/24/ios-uiviewcontroller-lifecycle/

A view controller's lifecycle, diagrammed


это для последних версий iOS (изменено с Xcode 9.3, Swift 4.1). Ниже приведены все этапы, которые делают жизненный цикл a UIViewController завершить.

loadView()

loadViewIfNeeded ()

viewDidLoad ()

viewWillAppear (_animated: Bool)

viewWillLayoutSubviews ()

viewDidLayoutSubviews()

viewDidAppear(_ анимированных: Боол)

viewWillDisappear (_animated: Bool)

viewDidDisappear (_animated: Bool)

позвольте мне объяснить все эти этапы.

1. loadView

это событие создает представление, которым управляет контроллер. Он вызывается только при программном создании контроллера представления. Это делает его хорошим местом для создания ваших представлений в коде.

This is where subclasses should create their custom view hierarchy if they aren't using a nib. 
Should never be called directly. 

2. loadViewIfNeeded

если incase представление текущего viewController еще не установлен, тогда этот метод загрузит представление, но помните, что это доступно только в iOS >=9.0. Поэтому, если вы поддерживаете iOS

Loads the view controller's view if it has not already been set.

3. метод viewDidLoad

на viewDidLoad событие вызывается только при создании и загрузке представления в память, но границы представления еще не определены. Это хорошее место для инициализации объектов, которые будет использовать контроллер представления.

Called after the view has been loaded. For view controllers created in code, this is after -loadView.
For view controllers unarchived from a nib, this is after the view is set.

4. viewWillAppear

это событие оповещает viewController всякий раз, когда появляется на экране. На этом шаге представление имеет определенные границы, но ориентация не задана.

Called when the view is about to made visible. Default does nothing.

5. viewWillLayoutSubviews

это первый шаг в жизненном цикле, где границы завершена. Если ты ... не используя ограничения или автоматическую компоновку, вы, вероятно, захотите обновить подвиды здесь. Это доступно только в iOS >=5.0. Поэтому, если вы поддерживаете iOS

Called just before the view controller's view's layoutSubviews method is invoked.
Subclasses can implement as necessary. The default is a nop.

6. viewDidLayoutSubviews

это событие уведомляет контроллер вида, что подвиды были настроены. Это хорошее место для внесения любых изменений в подвиды после их установки. Это доступно только в iOS >=5.0. Так что если вы поддерживают iOS

Called just after the view controller's view's layoutSubviews method is invoked.
Subclasses can implement as necessary. The default is a nop.

7. viewDidAppear

на viewDidAppear событие срабатывает после представления на экране. Что делает его хорошим местом для получения данных из серверной службы или базы данных.

Called when the view has been fully transitioned onto the screen.
Default does nothing

8. viewWillDisappear

на viewWillDisappear событие срабатывает, когда вид представлен viewController собирается исчезнуть, уволить, прикрыть или скрыть позади других viewController. Это хорошее место, где вы можете ограничить свои сетевые вызовы, аннулировать таймер или освободить объекты, которые связаны с этим viewController.

Called when the view is dismissed, covered or otherwise hidden.

9. viewDidDisappear

это последний шаг жизненного цикла, который любой может решить, как это событие срабатывает сразу после просмотра представленного viewController исчез, уволен, прикрыт или спрятан.

Called after the view was dismissed, covered or otherwise hidden. 
Default does nothing

теперь согласно Яблоко когда вы реализуя эти методы, вы должны помнить, чтобы вызвать super реализация этого конкретного метода.

If you subclass UIViewController, you must call the super implementation of this
method, even if you aren't using a NIB.  (As a convenience, the default init method will do this for you,
and specify nil for both of this methods arguments.) In the specified NIB, the File's Owner proxy should
have its class set to your view controller subclass, with the view outlet connected to the main view. If you
invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose
name is the same as your view controller's class. If no such NIB in fact exists then you must either call
-setView: before -view is invoked, or override the -loadView method to set up your views programatically.

надеюсь, что это помогло. Спасибо.

обновление - как @ThomasW указал внутри комментария viewWillLayoutSubviews и viewDidLayoutSubviews также будет вызываться в другое время при загрузке подвидов основного представления, например, при загрузке ячеек табличного представления или представления коллекции.


iOS 10,11 (Swift 3.1, Swift 4.0)

по данным UIViewController на UIKit разработчиков

1. loadView()

здесь подклассы должны создавать свою пользовательскую иерархию представлений, если они не используют Сиб. Никогда не следует звонить напрямую.

2. loadViewIfNeeded ()

загружает представление контроллера вида, если оно еще не было набор.

3. viewDidLoad ()

вызывается после загрузки представления. Для контроллеров представления, созданных в коде, это after-loadView. Для контроллеров представления, неархивированных из nib, это после установки представления.

4. viewWillAppear (_animated: Bool)

вызывается, когда представление собирается сделать видимым. По умолчанию ничего не делает

5. viewWillLayoutSubviews ()

вызывается сразу после метод layoutSubviews вид контроллера вид вызывается. Подклассы могут реализовываться по мере необходимости.

6. viewDidLayoutSubviews()

называется, когда размер,положение и ограничения применяются ко всем объектам.

7. viewDidAppear (_animated: Bool)

вызывается, когда представление полностью переведено на экран. По умолчанию ничего не делает

8. viewWillDisappear(_ анимированных: Боол)

вызывается, когда представление отклонено, закрыто или иным образом скрыто. По умолчанию ничего не делает

9. viewDidDisappear (_animated: Bool)

вызывается после того, как представление было отклонено, закрыто или иным образом скрыто. По умолчанию ничего не делает

10. viewWillTransition (размер: CGSize, с координатором: UIViewControllerTransitionCoordinator)

вызывается, когда вид Переход.

11. willMove (toparentviewcontroller родитель: UIViewController?)

12. didMove (toparentviewcontroller родитель: UIViewController?)

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

Родительский аргумент в обоих этих методах равен нулю, когда ребенок удален из родительского элемента; в противном случае он равен новому контроллеру родительского вида.

13. didReceiveMemoryWarning()

вызывается, когда родительское приложение получает предупреждение памяти. В iOS 6.0 он больше не будет очищать представление по умолчанию.


начиная с iOS 6 и выше. Новая диаграмма выглядит следующим образом:

enter image description here


методы viewWillLayoutSubviews и viewDidLayoutSubviews не упоминаются в диаграммах, но они называются между viewWillAppear и viewDidAppear. Их можно вызывать несколько раз.


ответ Хайдера верен для pre-iOS 6. Однако с iOS 6 viewDidUnload и viewWillUnload никогда не вызываются. The docs состояние: "представления больше не очищаются в условиях нехватки памяти, поэтому этот метод никогда не вызывается."


давайте сосредоточимся на методах, которые отвечают за UIViewController жизненный цикл:

  • создание:

    - (void)init

    - (void)initWithNibName:

  • посмотреть творение:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

    - (UIView *)initWithCoder:(NSCoder *)coder

  • обработка изменения состояния представления:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • памяти предупреждение обращение:

    - (void)didReceiveMemoryWarning

  • освобождение

    - (void)viewDidUnload

    - (void)dealloc

UIViewController's lifecycle diagram

для получения дополнительной информации, пожалуйста, взгляните на Ссылка На Класс UIViewController.


там много устаревшей и неполной информации. Для iOS 6 и новее только:

  1. loadView[a]
  2. viewDidLoad[a]
  3. viewWillAppear
  4. viewWillLayoutSubviews Это первый раз, когда границы завершены
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews[b]
  8. * viewDidLayoutSubviews[b]

Примечания:

(a) - если вы вручную обнуляете свой вид во время didReceiveMemoryWarning, loadView и viewDidLoad будет вызван снова. То есть, по умолчанию loadView и viewDidLoad вызывается только один раз для каждого экземпляра контроллера вида.

(b) можно назвать дополнительным 0 или более раз.


объяснение переходов состояний в официальном документе: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html

Это изображение показывает допустимые переходы состояния между различными методами обратного вызова view "will" и "did"


init(coder:)

при создании представлений вашего приложения в раскадровке,init(coder:) - это метод, который вызывается для создания экземпляра вашего контроллера вида и его оживления. Контракт для этого метода фактически определен в протоколе NSCoding, поэтому вы не увидите его в UIViewController документация.

когда этот метод вызывается, ваше представление, вероятно, будет отображаться когда-нибудь в ближайшем будущем (или в самом ближайшем будущем), но на данный момент нет никакой гарантии, что это на самом деле будет отображаться. Так что, возможно, сейчас самое время начать приводить все в порядок, но не слишком много, иначе вы потеряете вычислительную мощность. В этом методе можно создавать экземпляры зависимостей, включая вложенные представления, которые будут добавлены в представление программным способом. И обратите внимание, что init(coder:) вызывается только один раз в течение жизни объекта, как и все методы init.

viewDidLoad()

вызывается после init(coder:) когда представление загружается в память, этот метод еще называют, только один раз в срок службы объекта контроллера вида. Это отличное место для инициализации или настройки просмотра, которые вы не делали в раскадровке. Возможно, вы хотите добавить подвиды или ограничения автоматической компоновки программно – если это так, это отличное место для этого. Обратите внимание, что только потому, что представление было загружено в память, не обязательно означает, что оно скоро будет отображаться – для этого вы захотите посмотреть viewWillAppear. О, и не забудьте позвонить super.viewDidLoad() в вашей реализации, чтобы убедиться viewDidLoad вашего суперкласса получает шанс выполнить свою работу – я обычно называю super прямо в начале реализации.

viewWillAppear(_:)

всегда вызывается после viewDidLoad (по понятным причинам, если вы думаете об этом), и как раз перед тем, как представление появится на экране для пользователя,viewWillAppear называется. Это дает вам возможность выполнить любую настройку просмотра в последнюю минуту, запустить сетевой запрос (в другом классе, конечно) или обновить экран. В отличие от viewDidLoad, viewWillAppear называется первый время отображения представления, а также при повторном отображении представления, поэтому его можно вызывать несколько раз в течение срока службы объекта контроллера представления. Он вызывается, когда представление собирается появиться в результате нажатия пользователем кнопки "Назад", закрытия модального диалога, когда вкладка контроллера вида выбрана в контроллере панели вкладок или по ряду других причин. Обязательно позвоните super.viewWillAppear() в какой-то момент реализации-я обычно делаю это первым вещь.

viewWillDisappear(_:)

аналогично viewWillAppear этот метод вызывается непосредственно перед вид исчезает с экрана. И вроде viewWillAppear, этот метод может вызываться несколько раз в течение срока службы объекта контроллера вида. Он вызывается, когда пользователь переходит от экрана-возможно, отклоняя экран, выбирая другую вкладку, нажав кнопку, которая показывает модальное представление, или перемещаясь дальше вниз по иерархии навигации. Это отличное место, чтобы скрыть клавиатуру, сохранить состояние, и, возможно, отменить таймеры или сетевые запросы. Как и другие методы в жизненном цикле контроллера представления, обязательно вызовите super в какой-то момент viewWillDisappear.


согласно Apple docs

viewDidLoad - вызывается, когда создается и загружается из раскадровки представление содержимого контроллера вида (верхняя часть его иерархии представлений). Используйте этот метод для выполнения любой дополнительной настройки, требуемой контроллером представления.

viewWillAppear - вызывается непосредственно перед добавлением представления содержимого контроллера вида в иерархию представлений приложения. Используйте этот метод для запуска любых операций, которые должны произойти до представления содержимого на экране

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

viewWillDisappear - вызывается непосредственно перед тем, как представление содержимого контроллера вида удаляется из иерархии представлений приложения. Используйте этот метод для выполнения задач очистки, таких как фиксация изменений или изменение первого статус ответчика.

viewDidDisappear - вызывается сразу после того, как представление содержимого контроллера вида было удалено из иерархии представлений приложения. Используйте этот метод для выполнения дополнительных действий по демонтажу.