UIViewController的生命周期
生命周期
我们建立一个简单的模型来测试生命周期:新建两个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的生命周期的更多相关文章
- UIViewController的生命周期(根视图view从无到有的过程)
UIViewController的生命周期实质上是指根视图view从无到有的过程 1.首先新建一个工程:不从mainstoryBoard加载 (删除入口) 在AppDelegate.m --> ...
- UIViewController的生命周期及iOS程序执行顺序
UIViewController的生命周期及iOS程序执行顺序 当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc ...
- iOS程序的执行顺序 和 UIViewController的生命周期
iOS程序的执行顺序 1 进入程序的入口 进入main函数, 设置AppDelegate称为函数的代理 2 程序完成加载 -[AppDelegate application:didFinishLau ...
- iOS程序执行顺序 AppDelegate及 UIViewController 的生命周期
iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 iOS应用程序的状态切换很重要,而UIViewControler对于iOS这种MVC模式来说尤为重要 ...
- iOS程序执行顺序和UIViewController 的生命周期(整理)
说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序 ...
- IOS - UIViewController的生命周期
1)Load周期 2)Unload周期 在UIViewController中,view(黑体的view指的是controller的view属性)有两个循环:加载和卸载循环.当程序的一部分向contro ...
- UIViewController的生命周期及iOS程序执行顺序 和ios6 处理内存警告
当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc 创建对象,分配空间2.init (initWithN ...
- UIViewController的生命周期及iOS程序运行顺序
当一个视图控制器被创建,并在屏幕上显示的时候. 代码的运行顺序 1. alloc 创建对象,分配空间 2.init (initWit ...
- IOS第12天(3,UIViewController的生命周期)
#import "HMViewController.h" @interface HMViewController () @property(nonatomic,strong)NSA ...
随机推荐
- STL库的内存配置器(allocator)
正在学习中,如果有错,还请多多指教,根据不断的理解,会进行更改,更改之前的样子都会保留下来,记录错误是最大的进步,嗯嗯! 具有次配置力的SGI空间配置器(SGI是STL的一种版本,也有其他的版本) 这 ...
- Linux下修改mysql密码
# /etc/init.d/mysql stop# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &# mysq ...
- 如何设置eclipse字体及大小
1.打开eclipse菜单栏的Windows选项 2.选择其中的preference选项,界面如下图所示 3.选择General –> Appearance –> Colors and F ...
- Object 转化为String时的一个问题 null->"null"
近日在工作出了一个较大的问题,导致被客户投诉. 事情大致是,某个功能里新增对用户手机的修改,在平台数据同步过程中,出现了将用户以前的要同步的数据,那时还没有手机号码所以是null,新功能上线后,将手机 ...
- oracle 小题
create table student(sno varchar2(10) primary key,sname varchar2(20),sage number(2),ssex varchar2(5) ...
- jsp页面格式时间yy-mm-dd
这个问题把我花了1小时都没弄出来 各种报错 还是最后同学告知才知道的. 导入 :<%@ taglib uri="http://java.sun.com/jsp/jstl/func ...
- MongoDB学习笔记-06 数据库命令、固定集合、GridFS、javascript脚本
介绍MongoDB支持的一些高级功能: 数据库命令 固定大小的集合 GridFS存储大文件 MongoDB对服务端JavaScript的支持 数据库命令 命令的原理 MongoDB中的命令其实是作为一 ...
- U盘占空间,但看不到内容——解决方案
原因: u盘感染了病毒 .病毒把U盘里的文件都加上了隐藏属性和系统属性,所以看不到了,但仍占用存储空间. 解决办法: 1.在“运行“里面输入:cmd,回车:2.在cmd中进入U盘.比如你的U盘是H盘, ...
- 条件随机场理论分析CRF(Conditional Random Field)
- velocity导出word报错解决