iOS 控制器View加载顺序详细版

http://www.jianshu.com/p/e1ed4fe1f98c

加载过程:

1 一般情况下调用 init方法或者调用initWithNibName方法实例化UIViewController, 不管调用哪个方法都为调用initWithNibName(方法定义如下)

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

2 接着会调用loadView方法来生成UIViewController.view

- (void)loadView

下面来简单说下loadView底层

2.1.1.判断下有没有指定storyboard,如果有,就去加载storyboard描述的控制器的view
2.1.2.判断下有没有指定nibName,如果有,就去加载nibName描述的控制器的view

   - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

如果判断有没有指定nibName,[self nibName]
2.1.3判断下nibName是否为空,如果为空,他会尝试找下有没有跟控制器同名,但是不带Controller的xib
2.1.4跟控制器同名的xib,nibName = ViewController,但是这一步有条件,前提条件你没有重写loadView
2.1.5如果都没有找到,直接创建默认控制器的view

3 - (void)awakeFromNib;

这个方法用的时候,outlet还没有连接起来,是view Controller刚从storyboard建的时候,没有完全建好,不过可能有一些事情要在这个方法里面完成,比如splitViewDelegate,需要在非常早期完成。然后调用 viewDidLoad方法
4 - (void)viewDidLoad

如果loadView不能生成UIViewController.view系统将会反复调用loadView及viewDidLoad方法, 并且最终调用[super loadView] 方法返回UIViewController.view
然后依次调用如下2个方法, 这2个方法也十分重要, 在UINavigationController的POP操作后有时将要显示的UIViewController中的View并没有释放(也有可能释放掉) , UIViewController将不会调用上面的三个方法(initWithNibName,loadView,viewDidLoad) 而会调用下面这2个方法
5 - (void)viewWillAppear:(BOOL)animated;

6 - (void)viewDidAppear:(BOOL)animated;
紧接着调用下面两个方法view中frame值布局,使子控制器的frame值更加准确
7 - (void)viewWillLayoutSubviews
8 -(void)viewDidLayoutSubviews

9 卸载过程

- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)viewWillUnload;//iOS5.0添加
- (void)viewDidUnload;
- (void)dealloc;

控制器View一些方法的区分

viewDidLoad其实没什么可混淆的,无论通过什么途径加载(Xcode或者IB,这里的加载属于实例化)完view后肯定会执行这个方法.
loadView需要分两种情况.当你通过Xcode实例化一个类的时候就需要自己在controller中实现这个方法.而在IB中实例化就不需要实现它.
initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的.
awakeFromNib这个方法是一个类在IB中被实例化是被调用的.看了帖子发现大家都推荐使用viewDidLoad而不要使用awakeFromNib,应为viewDidLoad会被多次调用,而awakeFromNib只会当从nib文件中unarchive的时候才会被调用一次.实际测试中发现,当一个类的awakeFromNib被调用的时候,那么这个类的viewDidLoad就不会被调用了,这个感觉很奇怪.
initWithCoder是一个类在IB中创建但在Xcode中被实例化时被调用的.比如,通过IB创建一个controller的nib文件,然后在xocde中通过initWithNibName来实例化这个controller,那么这个controller的initWithCoder会被调用.
awakeFromNib 当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作。也就是说通过nib文件创建view对象是执行awakeFromNib

viewDidLoad 当view对象被加载到内存是就会执行viewDidLoad,所以不管通过nib文件还是代码的方式创建对象都会执行viewDidLoad



文/_那有只喵(简书作者)
原文链接:http://www.jianshu.com/p/e1ed4fe1f98c
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

猜你喜欢

转载自huqiji.iteye.com/blog/2327462
今日推荐