- 从打印结果可以看出,先调用loadView再调用viewDidload
- 代码:
//
// ViewController.m
// test
//
// Created by 裴波波 on 16/4/12.
// Copyright © 2016年 裴波波. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
-(void)loadView{
NSLog(@"loadView");
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"viewDidLoad");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
打印结果
看打印可以了解到先调用了loadview,再调用了viewDidload方法.
-
为什么分别调用了两次?
- loadView和viewDidLoad的区别就是,调用loadView时view还没有生成,调用viewDidLoad时,view已经生成了.
- 当调用loadview时,view为空, -> 调用viewdidload控制器仍然没有自己的view,此时再次调用loadview方法让控制器生成一个黑色的view.
- 注意点: 此时如果调用了loadview当时没有给viewController指定一个view的话,不能在viewdidload方法中用self.view = 某个view,此时如果调用view的set或者get方法都会使程序进入无限死循环中.看代码
viewDidload中
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%p",self.view);
NSLog(@"viewDidLoad");
}
打印结果
程序陷入无限循环
原因: 调用了self.view就相当于调用了loadview,由于重写loadview的方法时并没有给控制器的view指定一个view,所以会一直死循环下去...
解决办法之一就是在loadview方法中给self.view指定一个view
-(void)loadView{
UIView * view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
view.backgroundColor = [UIColor blueColor];
self.view = view;
NSLog(@"loadView");
}
此时打印结果
并且模拟器颜色为蓝色bluecolor
小结:调用loadview方法,要给控制器指定view.否则在viewdidload方法中调用self.view(view的set或者get方法)都会使程序进入死循环.
如果在loadview与viewdidload中都给控制器指定了view,那么从调用方法的顺序上看可以得到结果:最后被调用的viewdidload方法中的view会覆盖掉loadview中给控制器设置的view.
为了加深理解看官方文档
文档上说:当控制器的view为nil时,会调用这个方法,这个方法会创建一个view给控制器.
- 如果控制器从xib加载控制的view,则你可以调用此方法来加载xib--> initWithNibName:bundle: 或者不调用此方法,控制器会根据有没有一个xib名字跟控制器类名一样的,如果一样就加载这个跟控制器名字一样的xib文件作为控制的view.如果没有xib来初始化控制器的view的话,则这个方法loadview会创建一个空白的view给控制器.
- 如果用storyboard初始化控制器,就不用调用loadview方法了.
- 如果重写这个方法给控制器创建view则这个view必须是一个单例,而且不能被其他的控制器使用.并且不可以调用super
- 如果想初始化自定义的view,则在viewdidload中初始化即可.
综上:不建议使用loadview,可以根据自己的需要在storyboard或者viewdidload中创建自己需要的view给控制器.
视图控制器的生命周期