在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它。ViewController是IOS开发中MVC模式中的C,ViewController是view的controller,ViewController的职责主要包括管理内部各个view的加载显示和卸载,同时负责与其他ViewController的通信和协调。在IOS中,有两类ViewController,一类是显示内容的,比如UIViewController、UITableViewController等,同时还可以自定义继承自UIViewController的ViewController;另一类是ViewController容器,UINavigationViewController和UITabBarController等,UINavigationController是以Stack的形式来存储和管理ViewController,UITabBarController是以Array的形式来管理ViewController。和Android中Activity一样,IOS开发中,ViewController也有自己的生命周期(Lifecycle)。

首先来看看View的加载过程,如下图:

从图中可以看到,在view加载过程中首先会调用loadView方法,在这个方法中主要完成一些关键view的初始化工作,比如UINavigationViewController和UITabBarController等容器类的ViewController;接下来就是加载view,加载成功后,会接着调用viewDidLoad方法,这里要记住的一点是,在loadView之前,是没有view的,也就是说,在这之前,view还没有被初始化。完成viewDidLoad方法后,ViewController里面就成功的加载view了,如上图右下角所示。

在Controller中创建view有两种方式,一种是通过代码创建、一种是通过Storyboard或Interface Builder来创建,后者可以比较直观的配置view的外观和属性,Storyboard配合IOS6后推出的AutoLayout,应该是Apple之后主推的一种UI定制解决方案,后期我会专门介绍一篇使用AutoLayout进行UI制作的文章。言归正传,通过IB或Storyboard创建view,在Controller中创建view后,会在Controller中对view进行一些操作,会出现如下代码:

  1. @interface MyViewController()
  2. @property (nonatomic) IBOutlet id myButton;
  3. @property (nonatomic) IBOutlet id myTextField;
  4. - (IBAction)myAction:(id)sender;
  5. @end

这里用IBOutlet标记了一个UIButton和一个UITextField,用IBAction来标记UIButton的响应事件,IBOutlet和IBAction都是一个整形常量,用来标记控件,通过一张图能比较清晰的看清他们之间的关系:

上图中,MyViewController是继承自UIViewController的一个自定义ViewController,它包含两个View,一个是UIButton,一个是UITextField,从箭头的指向性上就可以比较好的理解IBOutlet和IBAction了。IBOutlet是告诉Interface Builder,此实例变量被连接到nib文件中的view对象,IBOutlet本身不做任何操作,只是一个标记作用。IBAction同样是个标记关键字,它只能标记方法,它告诉IB用IBAction标记的方法可以被某个控件触发。

通过编程的方式创建view,如下代码:

  1. - (void)loadView
  2. {
  3. CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
  4. UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame];
  5. contentView.backgroundColor = [UIColor blackColor];
  6. self.view = contentView;
  7. levelView = [[LevelView alloc] initWithFrame:applicationFrame viewController:self];
  8. [self.view addSubview:levelView];
  9. }

上述代码首先得到屏幕的frame,然后根据该frame生成了一个contentView,并指定当前ViewController的root view为contentView,然后生成了一个LevelView的自定义View并将它通过addSubview:方法添加到当前ViewController当中,完成view的初始化加载。

关于loadView方法的重写,官方文档中有一个明显的注释,原文如下:

Note: When overriding the loadView method to create your views programmatically, you should not call super. Doing so initiates the default view-loading behavior and usually just wastes CPU cycles. Your own implementation of the loadView method should do all the work that is needed to create a root view and subviews for your view controller.

意思是当通过代码方式去创建你自己的view时,在loadView方法中不应该调用super,如果调用[super loadView]会影响CPU性能。

接下来我们看看ViewController中的view是如何被卸载的:

从图中可以看到,当系统发出内存警告时,会调用didReceiveMemoeryWarning方法,如果当前有能被释放的view,系统会调用viewWillUnload方法来释放view,完成后调用viewDidUnload方法,至此,view就被卸载了。此时原本指向view的变量要被置为nil,具体操作是在viewDidUnload方法中调用self.myButton = nil;

小结一下:

loadView和viewDidLoad的区别就是,loadView时view还没有生成,viewDidLoad时,view已经生成了,loadView只会被调用一次,而viewDidLoad可能会被调用多次(View可能会被多次加载),当view被添加到其他view中之前,会调用viewWillAppear,之后会调用viewDidAppear。当view从其他view中移除之前,调用viewWillDisAppear,移除之后会调用viewDidDisappear。当view不再使用时,受到内存警告时,ViewController会将view释放并将其指向为nil。

ViewController的生命周期中各方法执行流程如下:

init—>loadView—>viewDidLoad—>viewWillApper—>viewDidApper—>viewWillDisapper—>viewDidDisapper—>viewWillUnload->viewDidUnload—>dealloc

加入我们的QQ群或微信公众账号请查看:Ryan's zone公众账号及QQ群

IOS学习笔记37——ViewController生命周期详解的更多相关文章

  1. Android学习笔记:Activity生命周期详解

    进行android的开发,必须深入了解Activity的生命周期.而对这个讲述最权威.最好的莫过于google的开发文档了. 本文的讲述主要是对 http://developer.android.co ...

  2. ios学习笔记之UIViewControl生命周期

    提到UIViewcontrol,每个人都不会陌生吧!平时实际开发中,每天的实际开发应该都少不了它.学过android的各位亲,也对生命周期这四个字并不陌生,无论是activity,还是service, ...

  3. MAVEN学习笔记之Maven生命周期和插件简介(3)

    MAVEN学习笔记之Maven生命周期和插件简介(3) clean compile site三套生命周期相互独立. clean pre-clean 执行清理前的工作 clean 清理上一次构建生成的所 ...

  4. ASP.NET生命周期详解

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  5. ASP.NET生命周期详解 [转]

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  6. IP地址和子网划分学习笔记之《IP地址详解》

    2018-05-03 18:47:37   在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. ...

  7. ASP.NET生命周期详解(转)

    看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...

  8. 零拷贝详解 Java NIO学习笔记四(零拷贝详解)

    转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...

  9. ASP.NT运行原理和页面生命周期详解及其应用

    ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用.  ...

随机推荐

  1. 任务28:RequestDelegate管道实现思路

    任务28:RequestDelegate管道实现思路 管道的实现机制 RequestDelegate是管道的核心.ApplicationBuilder就是接收了很多个RequestDelegae把它拼 ...

  2. UVa 11040 Add bricks in the wall (水题递推)

    题意:给定一个金字塔,除了最后一行,每个数都等于支撑它的两个数的和,现在给奇数行的左数奇数位置,求整个金字塔. 析:很容易看出来,从下往上奇数行等于 a[i][j] = (a[i-2][j-1] - ...

  3. UT源码 045

    (3)设计佣金问题的程序 commission方法是用来计算销售佣金的需求,手机配件的销售商,手机配件有耳机(headphone).手机壳(Mobile phone shell).手机贴膜(Cellp ...

  4. AppBoxFuture(七): 分布式外键约束

      关系数据库与NoSql其中的一个主要区别是具备完整的外键约束,虽说现在一些大厂在设计数据存储结构时禁止使用外键约束,靠业务逻辑来保证数据完整性,但考虑到是人就会犯错,为了保证关键业务数据的完整性, ...

  5. POJ2488【DFS】

    阿西吧,搞清楚谁是行,谁是列啊!!! #include <stdio.h> #include <string.h> #include <math.h> #inclu ...

  6. (三)SpringBoot定义统一返回result对象

    一:定义响应码枚举 package com.example.demo.core.ret; /** * @Description: 响应码枚举,参考HTTP状态码的语义 * @author * @dat ...

  7. 跟我一起玩Win32开发(1):关于C++的几个要点

    我不知道各位,一提起C++,第一感觉是什么?而据俺的观察,许多人几乎成了“谈C色变”.不管是C还是C++,一直以来都被很多人视为相当难学的玩意儿,幸好只是一个C++,没有C--,C**和C//,不然, ...

  8. 水题 Codeforces Round #304 (Div. 2) A. Soldier and Bananas

    题目传送门 /* 水题:ans = (1+2+3+...+n) * k - n,开long long */ #include <cstdio> #include <algorithm ...

  9. 1-20StringBuffer简介

    StringBuffer是一个字符串缓冲区,如果需要频繁的对字符串进行拼接时,建议使用StringBuffer. 工作原理 StringBuffer的底层是char数组,如果没有明确设定,则系统会默认 ...

  10. 525 Contiguous Array 连续数组

    给定一个二进制数组, 找到含有相同数量的 0 和 1 的最长连续子数组.示例 1:输入: [0,1]输出: 2说明: [0, 1] 是具有相同数量0和1的最长连续子数组. 示例 2:输入: [0,1, ...