initWithNibName和viewDidLoad执行顺序
转自:http://justsee.iteye.com/blog/1626231
众所周知,IB在加载nib的过程中存在着一些undocument行为,有的行为确实是不可理喻的,因此程序员对IB产生了抗拒心理。
今天我们要介绍的是IB导致的一个奇特行为。通过本文的描述, 作者完美地展示了IB给面向对象所带来的破坏作用。
我们有两个View Controller,暂名为superclass和subclass。subclass继承了superclass。
在superclass的initWithNibName初始化方法中:
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {
- [self setWords:@”somebody is knocking”];
- }
- return self;
在superclass的viewDidLoad方法中:
- [super viewDidLoad];
- NSLog(@"get XXX:%@", [self words]);
然后我们用subclass继承superclass。在initWithNibName方法中:
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {[
- [self setWords:@” pleaseanswer the door”];
- }
很显然,我们通过覆盖initWithNibName方法,修改了从superclass继承来的words属性。如果我们想打印pleaseanswer the door这段文本,你可能会想重用superclass的viewDidLoad方法:
- - (void)viewDidLoad{
- [super viewDidLoad];
- }
好了,运行程序。在加载superclass.xib时,控制台将打印somebodyis knocking。而加载subclass.xib时,控制台会打印pleaseanswer the door。
Hey,等一等。为什么我会在两个ViewController中都看到了somebody is knocking?
不用看了,subclass对象的words属性确实是please answer the door。如果你正在调试代码,那么可以debug区中确认这一点。
问题在于subclass的初始化出现了问题。看这一句:self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
这句代码将导致IB加载nib文件,并立即调用viewDidLoad方法。我们可以看到在初始化subclass时的调用顺序如下:
1. subclass->initWithNibName
2. superclass->initWithNibName
3. superclass->setWords
4. subclass->viewDidLoad
5. superclass->initWithNibName
6. subclass->setProperty
让我再解释一下:
1. 首先subclass的initWithNIbName方法调用。
2. 接着调用superclass的initWithNibName方法。
3. 在superclass的initWithNibName方法中,words属性被设置为somebodyis knoking。
4. superclass的initWithNibName方法结束,表示nib文件已加载,则调用nib文件的File’sowner所指向的 viewDidLoad方法。注意,这时的nib文件名应为subclass.nib,于是应调用[subclass viewDidLoad]方法。
5. subclass的viewDidLoad方法又调用了supclass的viewDidLoad方法。于是控制台打印出的是words属性的当前值somebodyis knoking。
6. 最后才是initWithNibName方法剩余的代码,在这里我们将words属性修改为pleaseanswer the door。但为时已晚,在此之前viewDidLoad已经执行结束。
解决的办法是简单的,不要在initWithName方法中修改从父类继承来的属性,相反,我们可以在[super iewDidLoad]之前这样做:
- (void)viewDidLoad{
[selfsetWords:@” pleaseanswer the door”];
[super viewDidLoad];
}
结论
由于initWithNibName或者是IB 这些限制,.nib文件违反了面向对象的原则。.nib文件无法从另一个.nib文件继承。不管你的类如何继承,但nib文件中不会保存类的层次结构,File’sowner也无法指向类链。
thx:http://blog.csdn.net/kmyhy/article/details/7236619
btw:
现在是
1. subclass->initWithNibName
2. superclass->initWithNibName
3. superclass->setWords
4. subclass->setWords
5. subclass->viewDidLoad
6. superclass->viewDidLoad
打印:在加载superclass.xib时,控制台将打印somebodyis knocking。而加载subclass.xib时,控制台会打印pleaseanswer the door。
以上ios6测试
initWithNibName和viewDidLoad执行顺序的更多相关文章
- initWithNibName与viewDidLoad的执行关系以及顺序
转载自:http://www.java123.net/v/380331.html 一个ViewController,一般通过init或initWithNibName来加载.二者没有什么不同,init最 ...
- 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模式来说尤为重要 ...
- UIViewController的生命周期及iOS程序执行顺序 和ios6 处理内存警告
当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc 创建对象,分配空间2.init (initWithN ...
- iOS程序执行顺序和UIViewController 的生命周期(整理)
说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序 ...
- Java的初始化块、静态初始化块、构造函数的执行顺序及用途探究
Java与C++有一个不同之处在于,Java不但有构造函数,还有一个”初始化块“(Initialization Block)的概念.下面探究一下它的执行顺序与可能的用途. 执行顺序 首先定义A, B, ...
- MonoBehaviour Lifecycle(生命周期/脚本执行顺序)
脚本执行顺序 前言 搭建一个示例来验证Unity脚本的执行顺序,大概测试以下部分: 物理方面(Physics) 渲染(Scene rendering) 输入事件(InputEvent) 流程图 Uni ...
- Unity中脚本的执行顺序总结(@WhiteTaken)
(Editor)以上是Unity官方文档中的截图,脚本在被挂载到物体上,会启用Editor的方法Reset. (Initialization)当执行脚本开始,初始化的过程中,依次执行的是Awake-& ...
随机推荐
- ABC定制视图导航控制器
ABCustomUINavigationController ABC定制视图导航控制器 Subclass of UINavigationController for overwriting ...
- ffmpeg中的sws_scale算法性能对比
sws_scale的算法有如下这些选择. #define SWS_FAST_BILINEAR 1#define SWS_BILINEAR 2#define SWS_BICUBIC 4#define S ...
- [Linux] Ubuntu下解压rar文件的方法
一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了rar解压工具之后,才可以解压.其实在ubuntu下安装rar解压工具是非常简单的,只需要两个步骤就可以迅速搞定. ubuntu 下r ...
- DCM4CHEE概述
DCM4CHEE构建概述: 所谓“磨刀不误砍柴工”,通过上面的知识普及,大致梳理了开源项目的应用流程.在下一篇博文开始正式介绍DCM4CHEE构建过程之前,先对DCM4CHEE进行一个简单的概述. d ...
- .net使用自定义类属性
.net中可以使用Type.GetCustomAttributes获取类上的自定义属性,可以使用PropertyInfo.GetCustomAttributes获取属性信息上的自定义属性. 下面以定义 ...
- MongoDB 复制一个collection里的数据到另一个collection
mongodb shell 中执行: db.source(复制源表).find().forEach(function(x){ db.target(目的表).insert(x); })
- Thinkphp学习笔记2-
因为操作方法就是控制器的一个方法,所以遇到有和系统的关键字冲突的方法可能就不能定义了,这个时候我们可以设置操作方法的后缀来解决,例如: 'ACTION_SUFFIX' => 'Action', ...
- Thinkpad X201 Gobi2000 上电信3G网络
网上的教程大多有点小问题,许多都不完整,今天放出系统化.理论化的设置方法,附送上所有软件. 一.本教程适用范围:1.gobi 2000 正式版 FRU:60Y3263 (带MEID.IMEI)2.- ...
- 【性能测试】Linux性能监控命令——sar详解
转载:https://blog.csdn.net/mig_davidli/article/details/52149993 sar命令可以从文件的读写情况.系统调用的使用情况.磁盘I/O.CPU效率. ...
- tomcat支持中文文件名下载
http://blog.csdn.net/wnczwl369/article/details/7483806 Tomcat 是Java开发者使用得较多的一个Web服务器,因为它占用资源小,运行速度快等 ...