UIViewController加载显示过程
2015-08-10 22:52
591 查看
在刚开始学习UIViewController的初始化过程时始终不理解loadView的内部详细流程,写出了这样的代码:
输出结果是:
可以看到loadView和viewDidLoad均未调用过。
经过一番研究之后终于弄清楚UIViewController的加载显示过程。
UIViewController的初始化将调用指定初始化方法:-(instancetype) initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil,参数nibNameOrNil为nib文件名和bundle的指针,均可以为nil。需要注意的是在需要指定NSBundle时指定了nil,则内部将会使用[NSBundler mainBundle]作为默认值。传入的参数分别保存到UIViewController的_nibName和_nibBundle两个实例变量中。
第一次使用getter获取视图控制器的view时,如果view为nil,则调用loadView函数。loadView函数分为三步:
2.1如果_nibName和_nibBundle值有效,则使用这两个值加载对应的nib文件以初始化view;
2.2_nibBundle和_nibName标识的资源无法找到,则使用视图控制器类名查找nib文件以初始化view;
2.3上述操作均无法初始化view时,创建空白的UIView作为视图控制器的view。
loadView加载view完毕,调用viewDidLoad。
经过以上分析,为UIViewController设置view的正确方法为:
直接使用IB构建界面,将文件名传入initWithNibName:bundle:
或者在代码中使用loadView的方式手工编写页面。
需要注意的是如果使用loadView手工编写页面,则无需在其内部调用父类的loadView,因为据对loadView的分析,如果需要Coding界面,则父类的操作可有可无,且耗费时间资源。但在viewDidLoad中需要对父类的ViewDidLoad进行调用。
在上面的代码中,应该将view的初始化移到loadView中,删除-(instancetype) initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil中对view的初始化:
#import "BNRHyposisViewController.h" #import "Hyposisview.h" @implementation BNRHyposisViewController { Hyposisview* _hyposisView; } -(instancetype) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ NSLog(@"call initWithNibName of BNRHyposisViewController"); self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { self.view=[[Hyposisview alloc] init]; [self.tabBarItem setTitle:@"Hyposis"]; [self.tabBarItem setImage:[UIImage imageNamed:@"Hypno"]]; } return self; } -(void)loadView{ NSLog(@"call loadView of BNRHyposisViewController"); } -(void) viewDidLoad{ [super viewDidLoad]; NSLog(@"call viewDidLoad of BNRHyposisViewController"); }
输出结果是:
Chapt6HypnoNerd[975:35311] call initWithNibName of BNRHyposisViewController
可以看到loadView和viewDidLoad均未调用过。
经过一番研究之后终于弄清楚UIViewController的加载显示过程。
UIViewController的初始化将调用指定初始化方法:-(instancetype) initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil,参数nibNameOrNil为nib文件名和bundle的指针,均可以为nil。需要注意的是在需要指定NSBundle时指定了nil,则内部将会使用[NSBundler mainBundle]作为默认值。传入的参数分别保存到UIViewController的_nibName和_nibBundle两个实例变量中。
第一次使用getter获取视图控制器的view时,如果view为nil,则调用loadView函数。loadView函数分为三步:
2.1如果_nibName和_nibBundle值有效,则使用这两个值加载对应的nib文件以初始化view;
2.2_nibBundle和_nibName标识的资源无法找到,则使用视图控制器类名查找nib文件以初始化view;
2.3上述操作均无法初始化view时,创建空白的UIView作为视图控制器的view。
loadView加载view完毕,调用viewDidLoad。
经过以上分析,为UIViewController设置view的正确方法为:
直接使用IB构建界面,将文件名传入initWithNibName:bundle:
或者在代码中使用loadView的方式手工编写页面。
需要注意的是如果使用loadView手工编写页面,则无需在其内部调用父类的loadView,因为据对loadView的分析,如果需要Coding界面,则父类的操作可有可无,且耗费时间资源。但在viewDidLoad中需要对父类的ViewDidLoad进行调用。
在上面的代码中,应该将view的初始化移到loadView中,删除-(instancetype) initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil中对view的初始化:
-(void)loadView{ self.view=_hyposisView=[[Hyposisview alloc] init ]; }
相关文章推荐
- [问与答]为什么 'a' in ('abc') 是True 而 'a' in ['abc'] 是False呢?
- [问与答]为什么 'a' in ('abc') 是True 而 'a' in ['abc'] 是False呢?
- 苹果开发 笔记(59)UIButton
- Math.abs为Integer.Min_VALUE返回错误的值
- UIlabel自适应高度和UITableViewCell自适应高度
- 【原创】驱动枚举之QueryServiceStatus
- UITableView编辑 增删改查
- 用UIImageView自带方法实现简单动画
- UIScrollView 偏移量和使用方法简单介绍
- UITextField 与 键盘
- Rescue
- 设置UItextfield边框颜色
- UIImageView 和UIButton
- CCBValue
- JAVA中String与StringBuffer,StringBuilder的区别
- OpenCV入门学习(三)HistogramEquivalent
- 自定义UICollectionViewLayout
- UITableView cell下拉菜单的做法
- UI_导航视图控制器
- UI09_重写Cell