iOS视图控制器的生命周期

我们去面试很多时候都被问到视图控制器的声明周期,下面我们着重来讲解下视图控制器的声明周期。

了解重要的三个函数

​视图控制器的声明周期我们讲解3个函数:1.loadView,2.viewDidLoad,3.viewDIdUnload。
​ 1.loadView是我们每次访问VC的view时而且view为nil时,loadView就会调用。loadVIew是用来创建VC的view的。默认的实现方式是下面这两个:
先去查找与VC相关的xib文件,通过xib文件来创建VC的view。
​如果初始化VC时指定了xib文件,就会根据xib文件名来加载对应的xib文件,比如我们代码是这样写的

ViewController *view = [[ViewController alloc]initWithNibName:@"ViewController" bundle:nil];

​如果没有明显的传xib文件就加载和他同名的xib文件,代码是这样的:

ViewController *view = [[ViewController alloc]init];

​上面这两种方式都是指有xib文件。

如果没有相关联的xib文件,就创建一个空白的view赋值给VC的view属性
​想要通过代码来创建view,就要重写loadVIew方法,并且不需要调用super的方法,我们既然要通过代码来创建UIView,那就没必要先创建一个空白的view,以节省不必要的开销,不需要调用[super loadView]。代码如下:

-(void)loadView{
   self.view = [[UIWebView alloc]init];
}

​ 2.无论通过代码还是xib,在view创建完成后肯定会调用viewDidLoad方法,一般会在这里做界面上的初始化操作,比如往view中添加一些subView,从数据库和网络加载数据显示到subView中。例如:

- (void)viewDidLoad
 {
     [super viewDidLoad];
​
     // 添加一个按钮
     UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
   [button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
   [self.view addSubview:button];
}

​ 3.iOS内存极其有限,如果应用程序占用内存过多的话,系统就会发出内存警告,VC就会受到didReceiveMemoryWarning消息,这个方法的默认实现是如果当前VC的view不在应用程序的视图层次结构中,即view的superView为nil时,就会将view释放并且调用viewdidUnload方法。这个方法有什么用,上面说到,发出内存警告且view被释放时就会调用viewdidUnload方法,所以释放资源主要与界面元素想的操作,将相关的实例赋值为nil。

- (void)viewDidUnload {
     [super viewDidUnload];
     self.name = nil;
     self.pwd = nil;
 }

​ 当发出内存警告只是调用了viewDidUnload,只是释放了view,并没有释放VC,所以viewDidUnload和dealloc没有任何的联系,dealloc只是在释放VC时调用。

三个函数的联系

​ 1.对此访问VC的view是,view为nil,然后调用loadView创建view。
​ 2.view创建完毕后会调用viewdidLoad方法进行界面元素的初始化。
​ 3.当内存警告是,系统可能会释放VC的view,将view赋值为nil,并且调用viewDidUnload方法。
​ 4.当再次访问VC的view时,view已经在3中被赋值为nil,所以又会调用loadView方法重新创建view。
​ 5.view被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化。

VC的生命周期

​ 我们通过下面两张图来说明,我们创建一个工程,然后在一个storyboard中拖一个按钮,然后点击按钮跳到下一个VC,看一下函数打印。

-[ViewController initWithCoder:]
-[ViewController loadView]
-[ViewController viewDidLoad]
-[ViewController viewWillAppear:]
-[ViewController viewDidAppear:]
​
//present BViewController
-[BViewController init]
-[BViewController initWithNibName:bundle:]
-[BViewController loadView]
-[BViewController viewDidLoad]
-[ViewController viewWillDisappear:]
-[BViewController viewWillAppear:]
-[BViewController viewDidAppear:]
-[ViewController viewDidDisappear:]

声明周期如下:
xib/storyboard(指文件存在) :initWithCoder 非xib\storyboard(需要手工创建):先调init,init本身又会调initWithNibName:bundle:

-loadView

-viewDidLoad

-viewWillAppear

-viewDidAppear

-viewWillDisappear

-viewDidDisappear

注意,从当前VC进入另一个VC的执行顺序
-[ViewController viewWillDisappear:]

-[BViewController viewWillAppear:]

-[BViewController viewDidAppear:]

[ViewController viewDidDisappear:]

在下一个VC完全出现后,才会调用前一个VC的完全消失,像需要不同控制器之间导航条隐藏与显示控制问题,就需要特别注意声明周期的顺序。

你可能感兴趣的:(iOS视图控制器的生命周期)