文章目录
![UIViewController生命周期](https://img-blog.csdnimg.cn/20190928171525982.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0MDA0OTAz,size_16,color_FFFFFF,t_70)
GitHub链接 测试代码
初始化
- initWithNibName
非storyBoard都走这个方法,进行视图控制器的初始化,初始化对象,初始化数据 - initWithCoder
如果链接了串联图storyBoard走这个方法
显示相关方法
-
loadView 加载视图
加载在viewController的view,
[super loadView],在loadView中创建自己的view可以不给frame,系统会自动设置控制器view的尺寸。在loadView方法中,如果没有给控制器的view赋值,就不能获取控制器的view,否则会造成死循环
比如下面,loadView中没有调用 [super loadView],所以就没有进行加载视图,即,ViewController的View为空,当viewDidLoad方法执行时,会发现视图为空,继续调用LoadView,就会陷入死循环- (void)loadView { NSLog(@"界面一 %s", __FUNCTION__); } //视图控制器中的视图加载完成, viewController自带的view加载完成 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSLog(@"界面一 %s", __FUNCTION__); }
打印结果
会发现,当打印到一定次数后,viewDidAppear,出现了,这应该是Xcode系统的一种防护机制,因为此时,并没有在ViewdidLoad方法中执行任何关于self.view的语句,系统出现防护机制
当在viewDidLoad中执行self.view相关语句时,- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSLog(@"界面一 %s", __FUNCTION__); self.view.backgroundColor = [UIColor redColor]; }
打印结果
则陷入了死循环,说明死循环是在self.view这句进行无限的循环。所以当重写loadView方法时,进行view的创建,就不用写[super loadView],而当只是直接打印东西,查看方法的执行顺序时,就要写上这句话。
-
viewDidLoad
当viewController的view对象加载入内存后,会进一步调用viewDidLoad方法来进行进一步设置,此时,视图层次已经放到内存中,通常,载入初始化数据,约束,视图等相关操作都可以在这个方法中实现。
系统在载入所有数据后,将会在屏幕上显示视图,先调用此方法,一帮,可以在此方法中对即将显示的视图做进一步的设置。还有就是,在多个视图切换时,在切换时,在这里对数据进行更新。
view即将布局其SubViews,比如view的bounds改变了,要调整SubViews的位置,在调整前要做的工作,可以放在这里实现。
view已经布局其subViews,可以在这里放调整后需要做的工作。
在视图正式显示时,或者视图切换时,调用此方法,在这里可以对正在显示的视图做设置。
消失
在视图切换时,当前视图即将消失,或者被覆盖时,调用此方法
view已经消失,或者被覆盖,
视图被销毁,在这里需要对在loadView和viewDidLoad中创建的对象,和通知要进行释放。
- didReceiveMemoryWaring
在内存过多的情况下,对于一些没有在显示的viewController会收到警告,然后会释放自己拥有的视图,相当于回到LoadView时的状态,以达到释放内存的目的。
视图切换时,方法调用的顺序(push和present)
打印效果
在界面一viewDidAppear方法执行后,界面二开始初始化。然后直到界面二完成viewDidLoad方法后,界面一才即将消失,然后界面二进行显示相关的方法,viewWillAppear一直到viewDidLayoutSubviews方法执行结束后,界面一消失。然后界面二显示。
-
点击返回按钮后
打印结果
可以看到点击返回后,界面二首先执行viewWillDisAppear方法,然后紧接着界面一执行ViewWillAppear方法,随后界面二消失,界面一显示后,界面二销毁。 -
点击present按钮
打印结果
同样是在界面一viewDidAppear之后界面二开始初始化,当界面二执行完viewDidLoad后,界面一将消失,执行viewWillDisappear方法,然后界面二开始显示,执行viewWillAppear方法,直到界面二ViewDidAppear方法执行后,界面一消失。这里与点击push之后,执行的顺序是不一样的。 -
didMiss后
打印结果
可以看到,界面二执行ViewWillDisappear方法,然后界面一开始准备显示,执行viewWillAppear方法紧接着显示,执行viewDidAppear方法,然后界面二消失,并销毁,这里也与pop界面二回到界面一,执行方法的顺序有点区别。
总结
- 从界面1无论是present到界面二,还是push到界面二,界面一都不会销毁,而从界面二返回到界面一,界面二会销毁。并且返回到界面一时, 因为之前并没有销毁,所以不执行viewWillLayoutSubViews和viewDIdLayoutSubviews方法。
- push-pop方法中,当界面布局完成后,没有显示之前,界面一消失,在pop时,当界面二消失后,界面一显示后,界面二才销毁。而在present-dismiss方法中,界面二显示后,界面一消失,在dismiss时,当界面一显示后,界面二消失并销毁。