iOS总结-UIViewController/UIView生命周期

参考: https://www.jianshu.com/p/d60b388b19f5

有关viewController的生命周期

storyBoard情况下的周期

非storyBoard下的周期

1.initWithNibName:bundle:
初始化UIViewController,执行关键数据初始化操作,非storyBoard创建UIViewController调用这个方法.
 不要在这里做view相关操作,view在loadview方法中才初始化.

2. initWithCoder:  
使用storyBoard进行视图管理,程序不会直接初始化一个UIViewController,storyBoard会自动初始化或在segue被触发时自动初始化,因此方法initWithNibName:bundle:不会被调用,但是initWithCoder:会被调用.

3.awakeFromNib
当方法被调用时,所有视图的outlet和action已经连接, 但还没有被确定,这个方法可以算作适合视图控制器的实例化配合一起使用的,因为有些需要根据用户喜好进行设置的内容,无法存在stortboard或xib中,可以在此方法中被加载尽量.

4.loadView
当执行到loadView方法时,如果视图控制器是通过nib创建,那么视图控制器已经从nib文件中被解档并创建好了,接下来任务就是对view进行初始化.

loadView方法是在UIViewController对象的view被访问且为空的时候调用.这是它与awakeFromNib方法的一个区别.
假设我们在处理内存警告时释放view属性:self.view = nil. 因此loadView方法在视图控制器的生命周期中可能被调用多次.

loadView方法不应该直接被调用,而是由系统调用.它会加载或创建一个view并把它赋值给UIViewController的view属性.

在创建view的过程中, 首先会根据nibName去找对应的nib文件然后加载.如果nibName为空或找不到对应的nib文件,则创建一个空视图,这种情况一般纯代码.

注:在重写loadView方法的时候,不要调用父类的方法.

5.viewDidLoad

当loadView将view载入内存中,会进一步调用viewDidLoad方法来进行进一步设置.此时,视图层次已经放到内存中,通常,我们对于各种初始化数据的载入,初始化设定/修改约束/移除视图等操作都可以在这个方法实现.

 视图层次 (view hierachy): 因为每个视图都有自己的子视图,这个视图层次其实也可以理解为一颗树状的数据结构.树的根节点,也就是根视图(root view), 在UIViewController中以view属性. 它可以看做是其他所有子视图的容器,也就是根节点.

6. viewWillAppear

系统载入所有数据后,将会在屏幕上显示视图,这时会先调用这个方法,通常我们会在这个方法对即将显示的视图做进一步的设置.如 设置设备不同方向该如何显示,设置状态栏方向/设置视图显示样式.

    当APP有多个视图时,上下级视图切换是也会调用这个方法,如果在调入视图时,需要对数据做更新,就只能在这个方法内实现.

7. viewWillLayoutSubviews  (将要布局子视图)

 view即将布局其Subviews. 如view的bounds改变了(例如:状态栏从不显示到显示,视图方法变化),要调整subviews的位置,在调整之前要做的工作可以放在该方法中实现.

8.viewDidLauoutSubviews
view已经布局其Subviews, 这里可以放置调整完成之后需要做的工作.

9.viewDidAppear
 在view被添加到视图层级中以及多视图,上下级视图切换时调用这个方法,在这里可以对正在显示的视图做设置.

10.viewWillDisappear
在视图切换时,当前视图在即将被移除/被覆盖时,会调用该方法,此时还没有调用removeFromSuperview.

11. viewDidDisappear
view已经消失/被覆盖,此时已经调用removeFromSuperView.

12. dealloc
视图被销毁,此次需要对你在init和viewDidLoad中创建的对象进行释放.

13.didReceiveMemoryWarning
在内存足够的情况下,app视图通常会一直保存在内存中,如果内存不够,会释放掉自己拥有的视图.系统只会释放内存,不会释放对象的所有权,通常我们需要在这里将不需要显示在内存中保留的对象释放它的所有权,置为nil.

只有init系列的方法,如intiWithNibName:Bundle:需要自己调用,其他的loadView/awakeFromNib,是系统自动调用,viewDidLoad系列方法类似于回调和通知,也会自动调用.

纯代码写视图布局时,要手动调用loadView方法,不能调用父类loadView. 纯代码和xib仅存在于loadView方法及其之前,编程时需要注意的也就是loadView方法.

initWithNibName:bundle:  和 awakeFromNib 整个生命周期里只会调用一次.

layoutSubViews方法由系统来调用,不能程序员来调用.可以调用setNeedsLayout进行标记,以保证UI下个刷屏系统中会调用layoutSubviews/layoutIfNeeded直接请求系统调用lauoutIfNeeded直接请求系统调用layoutSubviews.

layoutSubViews被调用时机:

1. addSubview会触发, 多次触发

2. view的frame改变/滚动UIScrollView/旋转Screen/改变transform属性

3.显示在最前面的keywindow的UIView才会被调用.

猜你喜欢

转载自blog.csdn.net/qq_28551705/article/details/84963667