「iOS」viewController的生命周期
iOS学习
- ViewController生命周期有关方法
- 案例
- 注意
ViewController生命周期有关方法
init
- 初始化程序;loadView
- 在UIViewController对象的view被访问且为空的时候调用;viewDidLoad
- 视图加载完成后调用;viewWillAppear
- UIViewController对象的视图即将加入窗口时调用;viewDidAppear
- UIViewController对象的视图已经加入窗口时调用;viewWillDisappear
- UIViewController对象的视图即将消失时调用;viewDidDisappear
- UIViewController对象的视图已经消失时调用;didReceiveMemoryWarning
- 出现内存警告。由于此处ViewController的view已经被释放了,ViewController中的空间可以在此处释放掉。dealloc
- 视图被销毁,此次需要对在init和viewDidLoad中创建的对象进行释放;
需要注意的是:
loadView和viewDidLoad的区别就是,loadView时view还没有生成,viewDidLoad时,view已经生成了,loadView只会被调用一次,而viewDidLoad可能会被调用多次(View可能会被多次加载),当view被添加到其他view中之前,会调用viewWillAppear,之后会调用viewDidAppear。
当view从其他view中移除之前,调用viewWillDisAppear,移除之后会调用viewDidDisappear。
当view不再使用时,受到内存警告时,ViewController会将view释放并将其指向为nil。
案例
创建A,B两个视图。
其中A视图代码:
#import "ViewController.h"
#import "secondVC.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"view1 Did Load");
// Do any additional setup after loading the view.
self.btn = [UIButton buttonWithType:UIButtonTypeSystem];
[self.btn setTitle:@"切换视图" forState:UIControlStateNormal];
self.btn.frame = CGRectMake(100, 100, 100, 50);
self.btn.center = self.view.center;
[self.btn addTarget:self action:@selector(pressbtn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.btn];
}
-(void)pressbtn
{
secondVC *secondvc = [[secondVC alloc] init];
[self presentViewController:secondvc animated:YES completion:nil];
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(@"view1将要显示");
}
-(void)viewDidAppear:(BOOL)animated
{
NSLog(@"view1已经显示");
}
-(void)viewWillDisappear:(BOOL)animated
{
NSLog(@"view1将要消失");
}
-(void)viewDidDisappear:(BOOL)animated
{
NSLog(@"view1已经消失");
}
@end
B视图代码:
#import "secondVC.h"
@interface secondVC ()
@end
@implementation secondVC
-(void)loadView
{
self.view = [[UIView alloc] init];
NSLog(@"view2正在加载");
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"view2 Did Load");
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blueColor];
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor redColor];
view.frame = CGRectMake(150, 300, 100, 100);
[self.view addSubview:view];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
[btn setTitle:@"切换视图" forState:UIControlStateNormal];
btn.frame = CGRectMake(100, 700, 100, 80);
[btn addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(@"view2将要显示");
}
-(void)viewDidAppear:(BOOL)animated
{
NSLog(@"view2已经显示");
}
-(void)viewWillDisappear:(BOOL)animated
{
NSLog(@"view2将要消失");
}
-(void)viewDidDisappear:(BOOL)animated
{
NSLog(@"view2已经消失");
}
-(void)press
{
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
最后我们得到运行结果:
第一个视图显示:
切换第二个视图:
返回第一个视图:
使用模态切换的方式切换视图时,会将第一个视图重新下载一遍。即重新执行一遍
viewDidLoad
方法。
而使用push方法切换视图时,则会发现,在第一个视图完全消失后,第二个视图才会加载好。这里直接给出运行结果。
注意
如果需要使用loadView
方法,要注意对view进行初始化,否则会进入死循环。
原因:若 loadView 没有加载 view,即为 nil,viewDidLoad 会一直调用 loadView 加载 view,因此构成了死循环,程序即卡死。
解决方法:
- 对view进行初始化赋值
- 使用[Supper LoadView]方法
- 在 ViewDidLoad 里创建 view,省略loadView方法。