ViewController的几种初始化方法的调用时机
以StoryBoard方式加载ViewController
我们新建一个项目的时候,默认生成的控制器就是根据Main.storyboard创建的。
此时相关方法的调用顺序为:
initWithCoder:
awakeFromNib
viewDidLoad
或者我们自己创建一个StoryBoard,然后通过它来创建控制器,调用顺序和上面是一样的。创建代码如下:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryBoard" bundle:[NSBundle mainBundle]];//这里的bundle 写nil也可以代表是mainBundle
MyViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"MyViewController"];
通过init或者initWithNibName: 创建ViewController
我们自定义的控制器,在别处以如下方式创建时:
MyViewController1 *vc1 = [[MyViewController1 alloc] init];
MyViewController2 *vc2 = [[MyViewController2 alloc] initWithNibName:@"MyViewController2" bundle:nil];
此时相关方法的调用顺序为:
initWithNibName:bundle:
loadView
viewDidLoad
总结
- 只要不是从StoryBoard创建的控制器,初始化控制器时,都会调用
initWithNibName:bundle
这个方法。注意,不要在这个函数中做view相关的操作,因为view在loadview方法中才初始化 - 如果使用StoryBoard进行视图管理,程序不会直接初始化一个UIViewController,StoryBoard会自动初始化。因此方法
initWithNibName:bundle
不会被调用,而是直接调用initWithCoder
。 - 只有在纯代码写视图布局的时候我们需要重写loadView方法,且loadView方法中不要调用
[super loadView]
- loadView和viewDidLoad的区别主要是:loadView只会被调用一次,viewDidLoad可能会被调用多次(因为其可能被多次加载)。loadView的时候view还没有生成,一直到viewDidLoad,才表示view生成成功。
UIView的创建
以纯代码的方式创建UIView
方法调用如下:
initWithFrame
以xib的方式加载UIView
如下:
UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil]lastObject];
方法调用为:
initWithCoder:(这个时候子控件没有被创建)
awakeFromNib(这个时候子控件创建完毕, 一般会在这里进一步对View进行初始化)