ViewController加载顺序与self.view

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ViewController加载顺序与self.view相关的知识,希望对你有一定的参考价值。

技术分享

从Stroyboard和xib中加载的ViewController的不同点在于

1、从Storyboard加载的ViewController只调用initWithCoder:方法,从xib加载的ViewController调用的是先执行initWithNibName:方法,后执行init方法。如果使用initWithNibName:方法初始化,则不会执行init方法;

2、从Storyboard里加载的ViewController,不能在initWithCoder:里面写self.view,而从xib里面创建的ViewController可以这么写。

3、对于不带xib的ViewController,只能使用init方法来进行初始化,使用initWithNibName:方法不能正常显示。使用init方法初始化的顺序如下:

log:

2014-12-26 15:36:07.857 St[269:9721] initWithNibName
2014-12-26 15:36:07.860 St[269:9721] init
2014-12-26 15:36:11.947 St[269:9721] viewDidLoad
2014-12-26 15:36:11.949 St[269:9721] viewWillAppear
2014-12-26 15:36:12.479 St[269:9721] viewDidAppear

*********************************

理论上,使用xib你的ViewController加载的顺序是按照上面写的顺序一样。没错,一点都没有错。

log:

2014-12-26 15:15:33.424 St[204:6297] initWithNibName
2014-12-26 15:15:33.431 St[204:6297] viewDidLoad
2014-12-26 15:15:33.432 St[204:6297] viewWillAppear

2014-12-26 15:15:33.966 St[204:6297] viewDidAppear

但是是,当你在initWithNibName方法里面用到了self.view的话,那么顺序可能就会有所变化了。

技术分享

看一下log:

log:

2014-12-26 15:32:58.024 St[253:9015] initWithNibName
2014-12-26 15:32:58.025 St[253:9015] befroe self.view in init
2014-12-26 15:32:58.030 St[253:9015] viewDidLoad
2014-12-26 15:32:58.031 St[253:9015] after self.view in init

2014-12-26 15:32:58.034 St[253:9015] viewWillAppear

 

2014-12-26 15:32:58.565 St[253:9015] viewDidAppear

当我们用到self.view的时候,会优先执行loadView和viewDidLoad两个方法,这两个方法再执行剩下的init部分的操作(接下来就执行appear方法的内容,不再执行刚刚执行过的loadView和viewDidLoadView方法)。使用的过程当中还是要注意的。

(我去,辛苦做的内容,最后发现viewDidLoad方法的花括号把队形打乱了。。。。。。

一、 ARC环境

  • 单个viewController的生命周期

    • initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)

    • loadView:加载view

    • viewDidLoad:view加载完毕

    • viewWillAppear:控制器的view将要显示

    • viewWillLayoutSubviews:控制器的view将要布局子控件

    • viewDidLayoutSubviews:控制器的view布局子控件完成
      这期间系统可能会多次调用viewWillLayoutSubviews 、 viewDidLayoutSubviews 俩个方法

    • viewDidAppear:控制器的view完全显示

    • viewWillDisappear:控制器的view即将消失的时候
      这期间系统也会调用viewWillLayoutSubviews 、viewDidLayoutSubviews 两个方法

    • viewDidDisappear:控制器的view完全消失的时候

  • 多个viewControllers跳转

    • 当我们点击push的时候首先会加载下一个界面然后才会调用界面的消失方法

    • initWithCoder:(NSCoder *)aDecoder:ViewController2 (如果用xib创建的情况下)

    • loadView:ViewController2

    • viewDidLoad:ViewController2

    • viewWillDisappear:ViewController1 将要消失

    • viewWillAppear:ViewController2 将要出现

    • viewWillLayoutSubviews ViewController2

    • viewDidLayoutSubviews ViewController2

    • viewWillLayoutSubviews:ViewController1

    • viewDidLayoutSubviews:ViewController1

    • viewDidDisappear:ViewController1 完全消失

    • viewDidAppear:ViewController2 完全出现

  • 小结:
    -整个控制器声明周期: viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear -> viewWillDisappear -> viewDidDisappear


二、非ARC环境下

  • didReceiveMemoryWarning:

    • 当app收到内存警告的时候会发消息给视图控制器。

    • app从来不会直接调用这个方法,而是当系统确定可用内存不足的时候采取调用。

    • 如果你想覆写这个方法来释放一些控制器使用的额外内存,你应该在你的实现方法中调用父类的实现方法

  • viewWillUnload:ios6废除)

    • 当消除掉控制器的视图之前调用

    • 视图不会再在低内存条件下被清除所以这个方法不会再被调用。

    • 在iOS5之前,当低的内存情况发生的时候,当前控制器的视图们不再被需要的时候,系统会有选择性的将这些视图从这些内存移除。这个方法被调用的目的是在视图被真正的销毁前你可以执行一些清空的任务。比如,你想要使用这个方法去清空视图的观察者或通知或者记录视图的状态以便当重新读取的时候恢复。

    • 在iOS6之后,不再需要清空视图的引用。因此,其他一些关于清理的方法,比如清空观察者,也不是必要的了。

  • viewDidUnload:(iOS6废除)

    • 当视图从内存中被消除后调用

    • 视图在地的内存情况下不再被销毁所以这个方法也不再会调用

    • 在iOS5之前,地的内存状况发生之后,当前的试图控制器的视图不再被需要,系统会选择性的在视图控制器的视图被销毁后调用。这个方法使你执行一些最后清空任务的最后机会如果你的视图控制器存储着对视图的或子控件的单独引用,你应该使用这个方法去释放这些引用。你也可以使用这个方法去消除一些你再创建视图时候所创建的但是当视图不再的时候不再需要的关于对象的引用。你不应该使用这个方法去释放用户数据或者一些不能轻易被重新创建的数据。

    • 在iOS6之后,清空在试图控制器中对views和其他对象的引用已经没有必要了。

    • 当这个方法被调用的时候,视图的属性是空的。


以上是关于ViewController加载顺序与self.view的主要内容,如果未能解决你的问题,请参考以下文章

UIViewController的生命周期及方法调用顺序

Swift 4,加载下一个 ViewController

Swift ViewController 在加载时崩溃

关于 viewController 的“viewDidLoad”和“viewWillAppear”方法

iOS程序执行顺序和UIViewController 的生命周期(整理)

如何从 Modal ViewController 重新加载父 UITableViewController 中的数据