viewController详解

一、生命周期当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序
1、 alloc                                   创建对象,分配空间
2、init (initWithNibName) 初始化对象,初始化数据
3、loadView                          从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图
4、viewDidLoad                   载入完成,可以进行自定义数据以及动态创建其他控件
5、viewWillAppear              视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6、viewDidAppear               视图已在屏幕上渲染完成
当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反
1、viewWillDisappear            视图将被从屏幕上移除之前执行
2、viewDidDisappear             视图已经被从屏幕上移除,用户看不到这个视图了
3、dealloc                                 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放
关于viewDidUnload :在发生内存警告的时候如果本视图不是当前屏幕上正在显示的视图的话,  viewDidUnload将会被执行,本视图的所有子视图将被销毁,以释放内存,此时开发者需要手动对viewLoad、viewDidLoad中创建 的对象释放内存。 因为当这个视图再次显示在屏幕上的时候,viewLoad、viewDidLoad 再次被调用,以便再次构造视图。

二、view的加载过程文字说明在表述流程的时候总是很费力的,我又找到了如下的两张图
跟随如下文字理解viewController对view加载过程:
1 先判断子类是否重写了loadView,如果有直接调用。之后调viewDidLoad完成View的加载。 2 如果是外部通过调用initWithNibName:bundle指定nib文件名的话,ViewController记载此nib来创建View。 3 如果initWithNibName:bundle的name参数为nil,则ViewController会通过以下两个步骤找到与其关联的nib。 A 如果类名包含Controller,例如ViewController的类名是MyViewController,则查找是否存在MyView.nib; B 找跟ViewController类名一样的文件,例如MyViewController,则查找是否存在MyViewController.nib。 4 如果子类没有重写的loadView,则ViewController会从StroyBoards中找或者调用其默认的loadView,默认的loadView返回一个空白的UIView对象。 注意第一步,ViewController是判断子类是否重写了loadView,而不是判断调用子类的loadView之后 ViewController的View是否为空。就是说,如果子类重写了loadView的话,不管子类在loadView里面能否获取到 View,ViewController都会直接调viewDidLoad完成View的加载。三、view卸载过程图
跟随以下文字理解卸载过程:
1 系统发出警告或者ViewController本身调用导致didReceiveMemoryWarning被调用 2 调用viewWillUnload之后释放View 3 调用viewDidUnload四、模拟器的调用顺序 我构架了这样一个环境,在该环境中有两个viewController,姑且命名为A和B,tag分别为1和2,A控制程序启动的时候即加载的界面,在A中放一个按钮,按下后会通过segue来调用到界面B;B 中页放一个按钮,通过执行 [self dismissModalViewControllerAnimated:YES]; 来返回界面A 然后检测所有的函数调用,依次如下 加载A的时候依次调用1 initWithCoder 1 loadView //如果说你进行了重写,会在这里调用,这一步可以参考下文 1 viewDidLoad 1 viewWillAppear 1 viewWillLayoutSubviews 1 viewDidLayoutSubviews 1 viewDidAppear切换至B的时候依次调用2 initWithCoder //先将2初始化 1 prepareForSegue //调用1的准备过度的函数,所以在该函数中可以对界面B的一些相关属性进行赋值 2 loadView //如果这里进行了重写 2 viewDidLoad //2界面加载 1 viewWillDisappear 2 viewWillAppear 2 viewWillLayoutSubviews 2 viewDidLayoutSubviews 2 viewDidAppear 1 viewDidDisappear从B切换回A的时候依次调用2 viewWillDisappear 1 viewWillAppear 1 viewDidAppear 2 viewDidDisappear 2 dealloc顺序总结下来加载依次为:加载 - 显示 - 布局 完成顺序依次为:完成布局 - 完成显示 - 完成加载小注:-(void)loadView;函数如果重写,下面是一个可能的demo-(void)loadView {CGRect applicationFrame = [[UIScreenmainScreen] applicationFrame];UIView *contentView = [[UIViewalloc] initWithFrame:applicationFrame];contentView.backgroundColor = [UIColordarkGrayColor];self.view = contentView;UILabel *lab = [[UILabelalloc]initWithFrame:CGRectMake(100, 100, 100, 100)];lab.text = @"HelloWorld";[self.viewaddSubview:lab]; }loadView虽然返回值为空,但必须在函数体内对self.view进行赋值,否则会在建立该界面的时候收到如下的log信息: Application windows are expected to have a root view controller at the end of application launch 具体执行顺序为:代码执行了initWithCoder之后直接调用了三次loadView函数,并且没有调用其它函数(包括viewDidLoad 、viewWillDisappear、viewWillLayoutSubviews) 疑问: 暂不清楚为什么会调用三次,我的猜测是:上述三个函数分别检测了一遍view是否存在,发现不存在,所以各自调用了一遍viewLoad,最后发现依然不存在,所以上述三个函数分别返回了失败,加载完成 但矛盾的地方是:为什么上述三个函数本身没有执行到?底层到底做了什么?五、view和ViewController的创建阶段,关于什么时候应该干什么 1、init Allocating critical data structures required by your view controller 不要出现创建view的代码。良好的设计,在init里应该只有相关数据的初始化,而且这些数据都是比较关键的数据。init里不要掉self.view,否则会导致viewcontroller创建view。(因为view是lazyinit的)。 2、loadView Creating your view objects 只初始化view,一般用于创建比较关键的view如tableViewController的 tabView,UINavigationController的navgationBar,不可掉用view的getter(在掉super loadView前),最好也不要初始化一些非关键的view。如果你是从nib文件中创建的viewController在这里一定要首先调用 super的loadView方法,但建议不要重载这个方法。 3、viewDidLoad Allocating or loading data to be displayed in your view 这时候view已经有了,最适合创建一些附加的view和控件了。有一点需要注意的是,viewDidLoad会调用多次(viewcontroller可能多次载入view,参见图2)。 4、viewWillAppear 这个一般在view被添加到superview之前,切换动画之前调用。在这里可以进行一些显示前的处理。比如键盘弹出,一些特殊的过程动画(比如状态条和navigationbar颜色)。 5、viewDidAppear 一般用于显示后,在切换动画后,如果有需要的操作,可以在这里加入相关代码。 6、viewDidUnload Releasing references to view objects Releasing data that is not needed when your view is not displayed 这时候viewController的view已经是nil了。由于这一般发生在内存警告时,所以在这里你应该将那些不在显示的view释放了。比 如你在viewcontroller的view上加了一个label,而且这个label是viewcontroller的属性,那么你要把这个属性设置 成nil,以免占用不必要的内存,而这个label在viewDidLoad时会重新创建。 7、dealloc Releasing critical data structures required by your view controller 六、几点备注: 1、按结构可以对iOS的所有ViewController分成两类: 1)、主要用于展示内容的ViewController,这种ViewController主要用于为用户展示内容,并与用户交互,如UITableViewController,UIViewController。 2)、用于控制和显示其他ViewController的ViewController。这种ViewController一般都是一个 ViewController的容器。如UINavigationController,UITabbarController。它们都有一个属 性:viewControllers。其中UINavigationController表示一种Stack式结构,push一个 ViewController或pop一次,因此后一个ViewController一般会依赖前一个ViewController。而 UITabbarController表示一个Array结构,各个ViewController是并列的。 第一种ViewController会经常被继承,用来显示不同的数据给用户。而第二种很少被继承,除非你真的需要自定义它。2、当view被添加其他view中之前时,会调用viewWillAppear,而之后会调用viewDidAppear。 当view从其他view中移出之前时,会调用viewWillDisAppear,而之后会调用viewDidDisappear。 当view不在使用,而且是disappeared,受到内存警告时,那么viewController会将view释放并将其指向nil。3、由于Controller加载View时,会自动将一些View对象指向其对应的IBOutlet变量。 所以当view被卸载时我们必须在viewDidUnload将这些变量release掉,ViewController不会自动做这件事。 具体做法是将变量设置为空,(注意和dealloc中将变量release的区别)注意此时Controller的view属性是空的。

 

转载于:https://www.cnblogs.com/lost-1987/articles/2886899.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/576105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Editplus For Python[转]

EditPlus是我常用的文件编辑器之一,用它来下脚本程序甚是方便,下面来看看如果配置吧: 1.先到www.editplus.com上下载editplus.exe,一步一步安装就好了,只有30天的试用期。 2.来配置python环境,到www.editpl…

硬件工程师在笔试中容易遇到的题目

名企硬件工程师面试考题大全 一、模拟电路 1、基尔霍夫定理的内容是什么?(仕兰微电子) 2、平板电容公式(CεS/4πkd)。(未知) 3、最基本的如三极管曲线特性。(未知) 4、描述反馈电路的概念&…

PyPyODBC 0.9.2发布 - 纯Python实现的pyodbc替代库

PyPyODBC发布了0.9.2版本,新版本加入了对Python 2.4的兼容性,加强了模块的健壮性,并修正了对Windows平台上Access MDB文件的创建和压缩功能。该模块的API语法尽力达到和著名的pyodbc库百分之百兼容,如果要在原有使用pyodbc的脚本上…

春节前51Aspx源码发布详情

材料科学与工程学院网站源码 2013-2-8 [VS2008] 本源码是为大学的一个学院网站定做的,现已经在某大学(不提名)网站上正式应用,且应用良好。本系统基于微软VS.net 2008 C# 、SQL Server2008,技术领先,完全模…

Java Swing 树状组件JTree的使用方法【图】

树中特定的节点可以由 TreePath(封装节点及其所有祖先的对象)标识,或由其显示行(其中显示区域中的每一行都显示一个节点)标识。展开 节点是一个非叶节点(由返回 false 的 TreeModel.isLeaf(node) 标识&…

实测java 与php运行速度比较

java如下 public class aa{ public static void main(String[] args){ System.out.println(System.currentTimeMillis()"----"); int a0; int i; for(i0;i<10000000;i){ a; } System.out.println(System.currentTimeMillis()); } } php如下 <? echo microtime…

C#多线程学习(一) 多线程的相关概念

什么是进程&#xff1f; 当一个程序开始运行时&#xff0c;它就是一个进程&#xff0c;进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 什么是线程&#xff1f; 线程是程序中的一个执行流&#xff0c;每个线程都有自己的专有寄存器…

java多线程编程基础

thread和runnable已经out了。取而代之的是callable<V>,它的结果存在future<V>中。后者有get对象可以阻塞并最终获得异步结果。FutureTask既是callable又是future。可以作为一个执行单元。 直接启动一个thread执行callable是不明智的&#xff0c;因为太多的短命的线…

Linux网络管理实 验 指 导

Linux网络管理 实 验 指 导 实验一 TCP/IP网络接口配置 一、实验目的 ● 掌握Linux下TCP/IP网络的设置方法。 ● 学会使用命令检测网络配置。 ● 学会启用和禁用系统服务。 二、项目背景 某企业新增了Linux服务器&#xff0c;在但还没有配置TCP/IP网络参数&#xff0…

开发iOS即时通讯工具参考的一些开源、框架和教程

转&#xff1a;http://www.ctolive.com/space.php?uid927&doblog&id2277 下面收集了开发即时通讯工具&#xff0c;如AIM、ICQ(Oscar 协议)以及Jabber(XMPP协议)的iOS客户端程序的一些开源&#xff0c;可以直接使用或者参考&#xff1a;Oscar协议开发库LibOrange&#…

HA双机热备配置

HA&#xff08;高可用性集群&#xff09;当主机处于工作状态时&#xff0c;从机处于休眠状态&#xff0c;当主机宕机时&#xff0c;从机便会开始工作&#xff0c;让用户几乎感觉不到服务的中断&#xff0c;类似于网络路由配置中的备份。当主机存活时&#xff0c;所有的资源全在…

我的服装DRP之开发感悟

先向各位拜个晚年。 今年过年期间都在想DRP的事&#xff0c;很多朋友也联系我&#xff0c;讨论技术问题的、谋求合作的、分析行业前景的、让我提供源码和数据库的都有。再次谢谢朋友们的关心。目前来说&#xff0c;在修改系统bug的同时&#xff0c;我打算重新找一份工作&#x…

Linux配置

第3章 对Linux系统管理员的建议... 1 第4章 安装Linux操作系统... 2 第5章 初步认识Linux. 5 第6章 Linux系统的远程登陆... 13 第7章 Linux文件与目录管理... 19 第8章 Linux系统用户及用户组管理... 37 第9章 Linux磁盘管理... 45 第10章 文本编辑工具vim.. 70 第11章…

iOS开发那些事-iOS常用设计模式–委托模式案例实现

书接上回&#xff0c;应用案例 我们以UITextFieldDelegate为例来说明一下委托的使用。 UITextFieldDelegate是控件UITextField的 委托&#xff0c;控件的委托主要负责响应控件事件或控制其他对象。除了UITextField&#xff0c;WebView、UITableView等控件也有相应的委托对象。 …

python网络编程-一些常用有用的函数

socket.getservbyname(servicename[, protocolname]) –> integer 查询某个协议对应的端口号&#xff0c;需要使用两个参数&#xff0c;servicename对应端口名称&#xff0c;如 http&#xff0c; smtp&#xff0c;等。protocolname对应tcp&#xff0c;udp。 s.getsockname()…

LAMP环境的搭建

一、mysql的安装1、tar -zxvf mysql.gz2、mv mysql-5.1.49-linux-i686-glibc23/ /usr/local/mysql3、cd /usr/local/mysql4、useradd -s /sbin/nologin -M mysql5、mkdir -p /data/mysql6、chown -R mysql:mysql /data/mysql/7、./scripts/mysql_install_db --usermysql --data…

Windows API 逐个逐个学MessageBox(5) 遍历驱动器并获取驱动器属性 GetLogicalDriveStrings、GetDriveTypeA...

首先还是贴代码 VC Code: /* *************************************《精通Windows API》 * 示例代码* GetVolumeInfo.c* 4.2.1 遍历驱动器并获取驱动器属性**************************************//* 头文件 */ #include <windows.h> #include <stdlib.h> #i…

apache如何在虚拟主机中实现用户验证

虚拟主机配置文件中&#xff0c;需要加入<Directory /data/web/test>AllowOverride AuthConfig</Directory>然后在虚拟主机的主目录&#xff0c;即DocumentRoot 目录下vi /data/web/test/.htaccess加入AuthName "frank share web" AuthType Basic Aut…

linux 内核编译安装及卸载

编译安装&#xff1a; 下载需要的包 apt-get install kernel-package libncurses5-dev fakeroot wget bzip2 cp linux-3.x.x /usr/src cd /usr/src/linux-3.x.x make menuconfig make modules make modules_install make make install sudo mkinitramfs -o /boot/initrd.img-3.…

Linux服务器安全之用户密钥认证登录(基于CentOS 7.0系统)

一、 密钥简介在Linux下&#xff0c;远程登录系统有两种认证方式&#xff1a;密码认证和密钥认证。密码认证方式是一种传统的安全策略。设置一个相对复杂的密码&#xff0c;对系统安全能起到一定的防护作用&#xff0c;但是也面临一些其他问题&#xff0c;例如密码暴力破解、密…