您的位置:首页 > 产品设计 > UI/UE

UIViewController加载显示过程

2015-08-10 22:52 591 查看
在刚开始学习UIViewController的初始化过程时始终不理解loadView的内部详细流程,写出了这样的代码:

#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 ];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: