之前自己一直好奇这些方法的执行顺序,于是就写了代码跑了一下。
最近在写一些 ViewController 跳转的库,于是测试了一下在两个 ViewController 跳转中的执行顺序。

先把结果贴出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
First viewDidLoad //1    
First viewWillAppear //2
First viewDidAppear //3
---Click Push
First viewWillDisappear //4
Second viewDidLoad //5
Second viewWillAppear //6
---Push Finish
First viewDidDisappear //7
Second viewDidAppear //8
---Click Pop
Second viewWillDisappear //9
First viewWillAppear //10
---Pop Finish
Second viewDidDisappear //11
First viewDidAppear //12

其实很多人都一定已经写过了这样的测试,如果你还没有,就亲自动手写一下,亲自实践检验一下结果,这个执行顺序了解一下,可以避免写出奇怪的 Bug 哦~

比如你还可以测试一下在 UITableViewController 中的 tableView 和 view 属性有什么区别。

我们简单来分析一下这个执行顺序:

  • Appear 前必须 Load
    必须是先加载视图才可以显示视图的,这点是最重要的,切不可以直观地认为 viewWillAppear 只执行一次。
  • 没有被销毁的 ViewController 不会再执行viewDidLoad()除非你再去无聊的调用一次(如果有什么迫不得已的原因最好也不要去直接调用)
  • 点击事件触发后,先调用的一定是当前所在的 viewController 中的方法,这里都是 viewWillDisAppear()

我们再来从客观规律的感觉一下~:

一个 viewController 想要出现,就必须先加载好自己要展示的东西再出现,就好比你上台演讲前要先把演讲稿准备好。等你演讲完,或者是下一个人要上来演讲,只有当你表明了你即将讲完,要离开了,下一个人才能准备演讲稿,准备上台。然后你下台了,下一个人也上来了。(理解起来并不恰当哈~)

其实简单点说,你可以理解成在屏幕中的 viewController 属于先手,遇到可能有争辩的顺序,都是在屏幕的 viewController 先执行(先将要消失)。

在 Click Push 到 Push Finish 之间是转换的过程,也就是动画的执行。就是说一些基本的动画你应该放在这里,比如在 viewController 中,从没有 navgationBar 的 viewController 到有 navgationBar 的 viewController 的跳转,设置的过程就可以选择在这里。最合适的地方就是viewWillAppear()了,如果你选择了viewWillDisAppear()实在是一个糟糕的决定,这个 viewController 都要消失了,你却要去设置它的各种状态,最后的结果只能是影响了下一个 viewController。

设置代码就像这样:

1
2
3
4
5
6
7
8
9
10
// FirstViewController (Blue)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: true)
}
// SecondViewController (Red)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(false, animated: true)
}

效果如图:


2016/2/16 更新,补充一份awakeFromNib()User Defined Runtime Attributes 的执行顺序。

先设置 User Defined Runtime Attributes 里面的东西,之后再去调用的awakeFromNib()哦。