UIViewController的生命周期

github测试链接

https://github.com/puyuerong/UIViewController

一些用到的方法:

1. init方法

初始化ViewController本身。

2. loadView方法

若loadView未加载view, 将导致ViewDidLoad和LoadView死循环

什么时候被调用?

每次访问UIViewController的view(比如controller.view、self.view)而且view为nil,loadView方法就会被调用。

  1. 有什么作用?

    loadView方法是用来负责创建UIViewController的view

  2. 默认实现是怎样的?

    默认实现即[super loadView]里面做了什么事情。
    它会先去查找与UIViewController相关联的xib文件,通过加载xib文件来创建UIViewController的view

    1> 如果在初始化UIViewController指定了xib文件名,就会根据传入的xib文件名加载对应的xib文件
    [[MJViewController alloc] initWithNibName:@“MJViewController” bundle:nil];

    如果没有明显地传xib文件名,就会加载跟UIViewController同名的xib文件
    [[MJViewController alloc] init]; // 加载MJViewController.xib

    2> 如果没有找到相关联的xib文件,就会创建一个空白的UIView, 然后赋值给UIViewController的view属性,大致如下

    self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
    

    [super loadView]里面就大致完成1>和2>中叙述的内容

3. viewDidLoad方法

当VC的view对象载入内存后调用,用于对view进行额外的初始化操作。
loadView时还没有view,而viewDidLoad时view已经创建好了。

4. viewWillAppear

在view即将添加到视图层级中(显示给用户)且任意显示动画切换之前调用
UIViewController对象的视图即将加入窗口时调用;

5. viewDidApper

UIViewController对象的视图已经加入到窗口时调用;

6. viewWillDisappear

UIViewController对象的视图即将消失、被覆盖或是隐藏时调用;

7. viewDidDisappear

UIViewController对象的视图已经消失、被覆盖或是隐藏时调用;

8. viewDidUnload方法

(释放无用内存)

当系统内存吃紧的时候会调用该方法,内存吃紧时,在iPhone OS 3.0之前didReceiveMemoryWarning是释放无用内存的唯一方式,但是OS 3.0及以后viewDidUnload方法是更好的方式。

在该方法中将所有IBOutlet(输出口)(无论是property还是实例变量)置为nil(系统release view时已经将其release掉了)。

在该方法中释放其他与view有关的对象、其他在运行时创建(但非系统必须)的对象、在viewDidLoad中被创建的对象、缓存数据等。

一般认为viewDidUnload是viewDidLoad的镜像,因为当view被重新请求时,viewDidLoad还会重新被执行。在ios6.0开始就废弃了,该方法不再会被调用。
替代;Memory warning

9. dealloc

调用
1、这个类被release的时候会被调用;
2、这个对象的retain count为0的时候会被调用;
或者说一个对象或者类被置为nil的时候;
释放其他资源或内存。

10. deinit

析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数,和OC中的dealloc 一样的,通常在deinit和dealloc中需要执行的操作有:
对象销毁
KVO移除
移除通知
NSTimer销毁
deinit {
// 注销通知 - 注销指定的通知
NotificationCenter.default.removeObserver(self,name: NSNotification.Name(rawValue: kUserDidLogin),object: nil)
}
控制器销毁时(离开堆),调用该方法。

11. viewWillLayoutSubviews

当一个视图的边界发生变化,也就是调整其子视图的位置。你的视图控制器可以重写此方法在layoutSubViews之前生效以重新布局子视图。该方法的默认实现不执行任何操作。
1、addSubview会触发viewWillLayoutSubviews

2、设置self.view及子视图的frame.size会触发layoutSubviews,当然前提是frame.size的值设置前后发生了变化,注意,此处不是origin,呼应官方文档上的边界发生变化

3、滚动一个UIScrollView(该scrollview有子视图的时候)会触发layoutSubviews

4、横竖屏幕切换会触发

12.viewDidLayoutSubviews

布局子视图结束时调用

UIViewController的生命周期

在这里插入图片描述

有两个界面界面1和界面2
Xcode更新后,有一个VC.modalPresentationStyle = UIModalPresentationFullScreen;显示的选型,如果是全屏显示的话,执行 present 操作的控制器的view和它的subViews,在 present 完成后都会被从当前视图层级移除,所以会有界面1的viewWillAppear和viewDidAppear,如果是别的模式,有的不会被移除,所以少了那两步。
UIModalPresentationStyle 各种类型的区别

由界面1present到界面2

2020-12-27 19:23:57.310009+0800 UIViewController的生命周期[9547:1039018] 

界面1  loadView
2020-12-27 19:23:57.311119+0800 UIViewController的生命周期[9547:1039018] 

界面1   开始viewDidLoad
2020-12-27 19:23:57.319895+0800 UIViewController的生命周期[9547:1039018] 

界面1  viewWillAppear
2020-12-27 19:23:57.325756+0800 UIViewController的生命周期[9547:1039018] 

界面1  viewWillLayoutSubviews
2020-12-27 19:23:57.325869+0800 UIViewController的生命周期[9547:1039018] 

界面1  viewDidLayoutSubviews
2020-12-27 19:23:57.351456+0800 UIViewController的生命周期[9547:1039018] 

界面1  viewDidAppear
2020-12-27 19:23:59.553414+0800 UIViewController的生命周期[9547:1039018] 

界面2  loadView
2020-12-27 19:23:59.554330+0800 UIViewController的生命周期[9547:1039018] 

界面2  viewDidLoad开始
2020-12-27 19:23:59.559186+0800 UIViewController的生命周期[9547:1039018] 

界面1  viewWillDisappear
2020-12-27 19:23:59.559402+0800 UIViewController的生命周期[9547:1039018] 

界面2  viewWillAppear
2020-12-27 19:23:59.561956+0800 UIViewController的生命周期[9547:1039018] 

界面2  viewWillLayoutSubviews
2020-12-27 19:23:59.562160+0800 UIViewController的生命周期[9547:1039018] 

界面2  viewDidLayoutSubviews
2020-12-27 19:24:00.065607+0800 UIViewController的生命周期[9547:1039018] 

界面2  viewDidAppear
2020-12-27 19:24:00.065993+0800 UIViewController的生命周期[9547:1039018] 

界面1  viewDidDisappear

界面2dismiss

2019-09-24 22:24:26.635852+0800 UIViewController的生命周期[1513:27192] 

界面2  viewWillDisappear
2019-09-24 22:24:26.735852+0800 UIViewController的生命周期[2446:73049] 

界面1  viewWillAppear
2019-09-24 22:24:29.972281+0800 UIViewController的生命周期[2446:73049] 

界面1  viewDidAppear
2019-09-24 22:24:32.042184+0800 UIViewController的生命周期[2446:73049] 

界面2  viewDidDisappear
2019-09-24 22:24:32.535861+0800 UIViewController的生命周期[2446:73049] 

界面2  dealloc

由点击push界面到点击pop界面

点击Push界面  loadView
2020-12-27 19:32:09.481357+0800 UIViewController的生命周期[9547:1039018] 

点击push界面   开始viewDidLoad
2020-12-27 19:32:09.487084+0800 UIViewController的生命周期[9547:1039018] 

点击Push界面  viewWillAppear
2020-12-27 19:32:09.489365+0800 UIViewController的生命周期[9547:1039018] 

点击Push界面  viewWillLayoutSubviews
2020-12-27 19:32:09.489539+0800 UIViewController的生命周期[9547:1039018] 

点击Push界面  viewDidLayoutSubviews
2020-12-27 19:32:09.492295+0800 UIViewController的生命周期[9547:1039018] 

点击Push界面  viewDidAppear

2020-12-27 19:32:37.248713+0800 UIViewController的生命周期[9547:1039018] 

点击Pop界面  loadView
2020-12-27 19:32:37.249957+0800 UIViewController的生命周期[9547:1039018] 

点击pop界面   开始viewDidLoad
2020-12-27 19:32:37.250845+0800 UIViewController的生命周期[9547:1039018] 

点击Push界面  viewWillDisappear
2020-12-27 19:32:37.251129+0800 UIViewController的生命周期[9547:1039018] 

点击Pop界面  viewWillAppear
2020-12-27 19:32:37.279286+0800 UIViewController的生命周期[9547:1039018] 

点击Pop界面  viewWillLayoutSubviews
2020-12-27 19:32:37.279474+0800 UIViewController的生命周期[9547:1039018] 

点击Pop界面  viewDidLayoutSubviews
2020-12-27 19:32:37.783578+0800 UIViewController的生命周期[9547:1039018] 

点击Push界面  viewDidDisappear
2020-12-27 19:32:37.783864+0800 UIViewController的生命周期[9547:1039018] 

点击Pop界面  viewDidAppear

点击pop界面到点击push界面

2019-09-25 00:25:01.367372+0800 UIViewController的生命周期[3551:112378] 

点击Pop界面  viewWillDisappear
2019-09-25 00:25:01.367535+0800 UIViewController的生命周期[3551:112378] 

点击Push界面  viewWillAppear
2019-09-25 00:25:01.875756+0800 UIViewController的生命周期[3551:112378] 

点击Pop界面  viewDidDisappear
2019-09-25 00:25:01.876707+0800 UIViewController的生命周期[3551:112378] 

点击Push界面  viewDidAppear
2019-09-25 00:25:01.877552+0800 UIViewController的生命周期[3551:112378] 

点击Pop界面  dealloc

总结

  1. 从界面1present界面2, 界面1不会销毁, 而在界面2dismiss, 界面2会销毁, 所以, 界面1到界面2, 总是要走LoadView, viewDidLoad, layOutSubViews这些方法, 而界面2dismiss会到界面1, 并不会重新走这些方法。

  2. viewDidAppear和viewDidDisappear
    在present-dismiss界面交互中
    要显示的界面完全显示之后, 上一界面才会消失
    在push-pop界面交互中‘上一个界面会先消失, 即将显示的界面才会显示。

  3. loadView中创建viewcontroller的view
    viewDidLoad中初始化显示在屏幕上的控件, 此时不布局。
    viewWillLayoutSubviews中布局各种view, 包括子视图的view。
    其他的方法大多只是提供了可以操作的时机。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值