期待了解iOS UIViewController生命周期

你能解释我pipe理UIViewController生命周期的正确方式吗?

特别是,我想知道如何在Mono Touch中为UIViewController类使用InitializeViewDidLoadViewWillAppearViewDidAppearViewWillDisappearViewDidDisappearViewDidUnloadDispose方法。

所有这些命令在iOS加载/显示/隐藏视图控制器时都会在适当的时候自动调用。 请注意,这些方法连接到UIViewController而不是连接到UIView本身。 你不会使用UIView获得任何这些function。

苹果公司的网站上有很棒的文档。 简单地说:

  • ViewDidLoad – 在创build类并从xib载入时调用。 非常适合初始设置和一次性工作。

  • ViewWillAppear – 在视图出现之前调用,适用于在视图可见之前每次隐藏/显示字段或任何想要发生的操作。 因为您可能会在视图之间来回切换,所以每当您的视图即将出现在屏幕上时,都会调用此视图。

  • ViewDidAppear – 在视图出现之后调用 – 启动animation或从API加载外部数据的好地方。

  • ViewWillDisappear / DidDisappear – 与ViewWillDisappear / DidDisappear相同。

  • ViewDidUnload / ViewDidDispose – 在Objective C中,这是你清理和释放东西的地方,但这是自动处理的,所以在这里你不需要做太多的事情。

UIViewController生命周期在这里图示:

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

视图控制器的生命周期,图表

这是最新的iOS版本。 主要有六个不同的阶段,使UIViewController的生命周期。 我按照顺序列出了它们。

的loadView

viewDidLoad中

viewWillAppear中

viewWillLayoutSubviews

viewDidLayoutSubviews

viewDidAppear

让我解释所有这些阶段。

  1. 的loadView

此事件创build控制器pipe理的视图。 只有在以编程方式创build视图控制器时才会调用它。 这使它成为在代码中创build视图的好地方。

  1. viewDidLoad中

viewDidLoad事件只有在视图被创build并加载到内存时才被调用。 但是这个观点的界限还没有定义。 这是初始化视图控制器将要使用的对象的好地方。

  1. viewWillAppear中

每当视图出现在屏幕上时,此事件通知视图控制器。 在这个步骤中,视图具有已定义的边界,但未定位方向。

  1. viewWillLayoutSubviews

这是边界最终确定的生命周期中的第一步。 如果您不使用约束或自动布局,则可能需要在此处更新子视图。

  1. viewDidLayoutSubviews

此事件通知视图控制器已设置子视图。 设置后,对子视图进行任何更改都是很好的select。

  1. viewDidAppear

视图出现在屏幕上后,viewDidAppear事件触发。 这使得它成为从后端服务或数据库获取数据的好地方。

希望这有助于。 谢谢。

从iOS 6开始。 新图如下:

在这里输入图像描述

Haider的答案在iOS 6之前是正确的。但是从iOS 6开始,viewDidUnload和viewWillUnload永远不会被调用。 文档陈述:“视图不再在低内存条件下清除,所以这个方法从来没有被调用。

viewWillLayoutSubviewsviewDidLayoutSubviews方法在图中没有提到,但在viewWillAppearviewDidAppear之间调用。 他们可以被多次调用。

这里有很多过时和不完整的信息。 仅适用于iOS 6和更高版本

  1. loadView [a]
  2. viewDidLoad [a]
  3. viewWillAppear
  4. viewWillLayoutSubviews是第一次界定
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews [b]
  8. * viewDidLayoutSubviews [b]

脚注:

(a) – 如果您在didReceiveMemoryWarning过程中手动清除了视图,则会再次调用loadViewviewDidLoad 也就是说,默认情况下, loadViewviewDidLoad仅在每个视图控制器实例中被调用一次。

(b)可以被称为额外的0次或更多次。

让我们专注于负责UIViewController生命周期的方法:

  • 创build:

    - (void)init

    - (void)initWithNibName:

  • 视图创build:

    - (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的生命周期图

有关更多信息,请参阅UIViewController类参考 。

在官方文档中解释状态转换: https : //developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html

该图显示了各种视图'will'和'did'callback方法之间的有效状态转换

有效的状态转换

iOS 10,11 (Swift 3.1,Swift 4.0)

根据UIKit开发者的UIViewController

1. loadView()

这是子类应该创build自定义视图层次的地方,如果他们不使用笔尖。 不应该直接调用。

2. loadViewIfNeeded()

如果尚未设置,则加载视图控制器的视图。

3. viewDidLoad()

视图加载完成后调用。 对于在代码中创build的视图控制器,这是after-loadView。 对于从笔尖取消存档的视图控制器,这是在视图设置之后。

4. viewWillLayoutSubviews()

在视图控制器视图的layoutSubviews方法被调用之后调用。 子类可以根据需要实现。

5. viewDidLayoutSubviews()

当尺寸,位置和约束条件应用于所有对象时调用。

6. viewWillAppear(_ animated:Bool)

当视图即将显示时调用。 默认什么都不做

7. viewDidAppear(_ animated:Bool)

当视图完全转换到屏幕上时调用。 默认什么都不做

8. viewWillDisappear(_ animated:Bool)

当视图被解散,覆盖或以其他方式隐藏时调用。 默认什么都不做

9. viewDidDisappear(_ animated:Bool

在视图被解散,覆盖或以其他方式隐藏之后调用。 默认什么都不做

10. viewWillTransition(大小:CGSize,协调器:UIViewControllerTransitionCoordinator)

当视图正在转换时调用。

11. willMove(toParentViewController父:UIViewController?)

12. didMove(toParentViewController父级:UIViewController?)

在子控制器之间转换时,这两个方法是公用的,用于调用容器子类。 如果他们被覆盖,覆盖应确保打电话给超级。

这两个方法中的父参数是零,当一个孩子被从其父母移除; 否则等于新的父视图控制器。

13. didReceiveMemoryWarning()

父应用程序收到内存警告时调用。 在iOS 6.0上,默认情况下将不再清除视图。

 init(coder:) 

在Storyboard中创build应用程序的视图时, init(coder:)是被调用来实例化视图控制器并使其init(coder:)的方法。 这个方法的契约实际上是在NSCoding协议中定义的,所以你不会在UIViewController文档中看到它。

当这个方法被调用时,你的视图很可能会在不久的将来(或者不久的将来)显示出来,但是在这一点上并不能保证它真的被显示出来。 所以这可能是开始整理事物的好时机,但这里不要太多,否则会浪费处理能力。 在这个方法中,你可能实例化依赖关系,包括你将以编程方式添加到视图中的子视图。 注意init(coder:)只在对象的生命期间被调用一次,因为所有的init方法都是。

 viewDidLoad() 

在视图加载到内存之后调用init(coder:)之后,此方法在视图控制器对象的生命周期中也只调用一次。 这是一个很好的地方做任何视图初始化或设置你没有在故事板做。 也许你想以编程方式添加子视图或自动布局约束 – 如果是这样,这是做这两个任务的好地方。 请注意,只是因为视图已经加载到内存中并不一定意味着它将很快显示 – 为此,您将需要查看viewWillAppear 。 哦,记得在你的实现中调用super.viewDidLoad() ,以确保你的超类的viewDidLoad有机会做它的工作 – 我通常在实现开始时调用超级权利。

 viewWillAppear(_:) 

总是在viewDidLoad之后调用(出于显而易见的原因,如果你仔细想一下),并且在视图出现在用户的屏幕上之前,调用viewWillAppear 。 这使您有机会做任何最后一分钟的视图设置,启动一个networking请求(当然在另一个class级),或者刷新屏幕。 与viewDidLoad不同的是, viewWillAppear在第一次显示视图时以及再次显示视图时调用,因此可以在视图控制器对象的生命期内多次调用viewWillAppear 。 当用户点击后退button,closures模式对话框,在选项卡栏控制器中select视图控制器的选项卡或其他各种原因时,视图即将出现。 确保在实现中的某个时刻调用super.viewWillAppear() ,我通常首先执行它。

 viewWillDisappear(_:) 

viewWillAppear类似,在视图从屏幕消失之前调用此方法。 和viewWillAppear一样,这个方法在视图控制器对象的生命期间可以被多次调用。 当用户离开屏幕时,可能会调用它 – 可能会解散屏幕,select另一个选项卡,点击显示模式视图的button,或者沿着导航层级进一步导航。 这是隐藏键盘,保存状态,并可能取消运行定时器或networking请求的好地方。 与视图控制器生命周期中的其他方法一样,请确保在viewWillDisappear中的某个点处调用super