生命周期

我们建立一个简单的模型来测试生命周期:新建两个ViewController,一个是主视图控制器(main ViewController,以下简称mainVC),一个是副视图控制器(sub ViewController,以下简称subVC),在mainVC里点击一个Button,以modal方式切换至subVC,然后在subVC里点击另一个Button关闭subVC并返回mainVC。我们将这两个控制器的每个状态都打印出来,各个阶段的执行如下:

case 1. 第一次运行app:

main loadView

main viewDidLoad

main viewWillAppear

main viewDidAppear

case 2. 在mainVC里点击Button,以modal方式切换至subVC:

sub loadView

sub viewDidLoad

main viewWillDisappear

sub viewWillAppear

sub viewDidAppear

main viewDidDisappear

case 3. 在subVC里点击Button关闭subVC并返回mainVC

sub viewWillDisappear

main viewWillAppear

main viewDidAppear

sub viewDidDisappear

sub dealloc

当一个视图控制器被创建,并在屏幕上显示的时候代码的执行顺序:

step 1:alloc 创建对象,分配空间

step 2:init (initWithNibName) 初始化对象

step 3:loadView 从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图

step 4:viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件

step 5:viewWillAppear 视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了

step 6:viewDidAppear 视图已在屏幕上渲染完成

当一个视图控制器被移除屏幕并且销毁的时候的执行顺序:

step 1:viewWillDisappear 视图将被从屏幕上移除之前执行

step 2:viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了

step 3:dealloc 视图被销毁

这里需要说一下loadView与viewDidLoad的区别:当loadView时,还没有view;而viewDidLoad时,view已经创建好了。详细的加载循环:

step 1:程序请求ViewController的view属性

step 2:如果view在内存中,则直接加载;如果不存在,则调用loadView方法

step 3:loadView方法执行如下方法:

  • 如果重载了这个方法,则必须创建必要的UIView并且将一个非nil值传给ViewController的view属性。
  • 如果没有重载这个方法,ViewController会默认使用自己的nibName和nibBundle属性尝试从nib文件加载view。如果没有找到nib文件,它尝试寻找一个与ViewController类名匹配的nib文件。
  • 如果没有可用的nib文件,那么它创建一个空的UIView作为它的view。

最后还要考虑一个重要的情况:内存不足警告。当程序收到内存警告的时候,会调用每一个ViewController的didReceiveMemoryWarning方法,我们需要做出相应,释放程序中暂时不需要的资源;通常都会重写该方法,但记得重写的时候要调用super的该方法。

iOS3.0 - iOS6.0期间,didReceiveMemoryWarning方法会判断当前ViewController的view是否显示在window上,如果没有显示在window上,则didReceiveMemoryWarning会自动将ViewController的view以及其所有子view全部销毁,然后调用View Controller的viewDidUnload方法。但是从iOS6.0开始,viewDidUnload和viewWillUnload这两个方法已被废除,收到low-memory时系统不会释放view,而只是释放controller的resource。

一种常见处理内存警告的方式:

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning]; float ver = [[[UIDevice currentDevice] systemVersion] floatValue]; if(ver >= 6.0f)
{
if(self.isViewLoaded && !self.view.window)
{
self.view = nil; //确保下次重新加载
}
}
}

上面的代码先取得当前iOS系统的版本号,如果是iOS6.0或以上版本,进一步判断视图是否被装载进内存,并且是否为当前视图,在这两个条件都满足(已经装载进内存&&不是当前视图)时,将self.view设置为nil,这样就能保证再调用该ViewController时,loadView和viewDidLoad被再次调用。

我们在xcode调试器里模拟内存警告,监控此时切换的状态:

case 4. 当已切换至subVC,模拟内存警告,并返回mainVC,不处理didReceiveMemoryWarning。

Received memory warning.

main didReceiveMemoryWarning

sub didReceiveMemoryWarning

sub viewWillDisappear

main viewWillAppear

main viewDidAppear

sub viewDidDisappear

sub dealloc

case 5. 当已切换至subVC,模拟内存警告,并返回mainVC,处理didReceiveMemoryWarning。

Received memory warning.

main didReceiveMemoryWarning

sub didReceiveMemoryWarning

main loadView

main viewDidLoad

sub viewWillDisappear

main viewWillAppear

main viewDidAppear

sub viewDidDisappear

sub dealloc

可以很明显的看出,当处理了didReceiveMemoryWarning后,重新执行了非当前视图的loadView和viewDidLoad方法。

init/initWithCoder

loadView

viewDidLoad

viewWillAppear

viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear
viewWillDisappear
viewDidDisappear

UIViewController的生命周期的更多相关文章

  1. UIViewController的生命周期(根视图view从无到有的过程)

    UIViewController的生命周期实质上是指根视图view从无到有的过程 1.首先新建一个工程:不从mainstoryBoard加载 (删除入口) 在AppDelegate.m --> ...

  2. UIViewController的生命周期及iOS程序执行顺序

    UIViewController的生命周期及iOS程序执行顺序     当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc                         ...

  3. iOS程序的执行顺序 和 UIViewController的生命周期

    iOS程序的执行顺序 1 进入程序的入口 进入main函数, 设置AppDelegate称为函数的代理 2  程序完成加载 -[AppDelegate application:didFinishLau ...

  4. iOS程序执行顺序 AppDelegate及 UIViewController 的生命周期

    iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 iOS应用程序的状态切换很重要,而UIViewControler对于iOS这种MVC模式来说尤为重要 ...

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

    说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序 ...

  6. IOS - UIViewController的生命周期

    1)Load周期 2)Unload周期 在UIViewController中,view(黑体的view指的是controller的view属性)有两个循环:加载和卸载循环.当程序的一部分向contro ...

  7. UIViewController的生命周期及iOS程序执行顺序 和ios6 处理内存警告

    当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc                                   创建对象,分配空间2.init (initWithN ...

  8. UIViewController的生命周期及iOS程序运行顺序

    当一个视图控制器被创建,并在屏幕上显示的时候. 代码的运行顺序 1. alloc                                   创建对象,分配空间 2.init (initWit ...

  9. IOS第12天(3,UIViewController的生命周期)

    #import "HMViewController.h" @interface HMViewController () @property(nonatomic,strong)NSA ...

随机推荐

  1. 【章老师的课程】Black Box Testing

    本周我们学习了黑盒测试,这是一种常用的软件测试方法,它将被测软件看作一个打不开的黑盒,主要根据功能需求设计测试用例,进行测试.本章主要介绍几种常用的黑盒测试方法和黑盒测试工具,并通过实例介绍各种方法的 ...

  2. Kiwi iOS驱动测试开发

    Kiwi是iOS开发一个行为驱动开发库.目标是提供一个BDD库,精美的简单安装和使用. 安装 使用CocoaPods安装: pod 'Kiwi'如果使用Xcode5则使用: pod 'Kiwi/XCT ...

  3. jQuery in action 3rd - Working with properties, attributes, and data

    properties properties 是 JavaScript 对象内在的属性,可以进行动态创建,修改等操作. attributes 指的是 DOM 元素标记出来的属性,不是实例对象的属性. 例 ...

  4. 黑马程序员_Java基础:JDK1.5后的新特性:自动拆装箱,以及注意事项

    ------- android培训.java培训.期待与您交流! ---------- 首先来看一段代码: Integer x = new Integer(4); Integer y = 4; 在JD ...

  5. CentOS防火墙问题

    问题背景 在Vmware虚拟机中安装了 CentOS 7 的 Linux 版本,并在其中安装了 Oracle 11g 数据库,数据库可以在虚拟机中顺利启动,本地主机也可以 ping 通 linux.准 ...

  6. GIT FLOW 时序图

    git flow sequence md link: git branching model master->master branch: use default branch Note rig ...

  7. 河南省第五届ACM程序设计大赛

    D:   遥 控 器 #include<cstdio> #include<cstring> #include<iostream> #include<algor ...

  8. XStream学习笔记

    XStream 所需jar包: xstream-1.3.jar xpp3_min-1.1.4c.jar xmlpull-1.1.3.1.jar 目录: 1.注解去除,标签中带有包名的节点 2.注解修改 ...

  9. 设置UIButton或者UILabel显示文字的行数

    需要在UIButton的titleLabel或者UILabel的text 字符串里面添加换行符号 “\n”,并且设置 UILabel的numberOfLines属性 栗子:行数要和“\n”的个数对应, ...

  10. Vagrant 启用 rsync

    折腾了那么久,发现这些smb,nfs,virtualcfs,这些同步方案在windows下都不是最完美的.最完美的还是 rsync,我使用它同步windows上的代码,在windows浏览器中打开虚拟 ...