ViewController
是iOS
开发中MVC
模式中的C
,ViewController
是view
的Controller
,ViewController
的职责主要包括管理内部各个view
的加载显示和卸载,同时负责与其他ViewController
的通信和协调。
分类
在iOS中,有两类ViewController
,一类是显示内容的,比如UIViewController
、UITableViewController
等,同时还可以自定义继承自UIViewController
;另一类是ViewController
容器,UINavigationController
和UITabBarController
等,UINavigationController
是以Stack
的形式来存储和管理ViewController
,UITabBarController
是以Array
的形式来管理ViewController
。
加载过程
在Controller
中创建View
有两种方法,一种是使用Storyboard
等可视化工具,另一种是通过代码创建。
可视化工具在开发中方便快捷,但是流畅性不如纯代码的方式创建。
ViewController生命周期
alloc->initWithNibName->loadView->viewDidLoad->viewWillAppear->viewDidAppear->viewWillDisappear->viewDidDisappear->dealloc
注意viewWillUnload
和viewDidUnload
已经在iOS6
被废弃了,因为Clearing references to views is no longer necessary
.
注意:没有viewWillLoad
注意:viewDidLoad
和viewDidUnload
并不是成对的。
程序运行中按下Home
键,程序并没有以上方法的触发,但双击Home
键,删除该程序将会触发,View Will Disappear
和View Did Disappear
两个方法。
为什么按下Home
键之后没有调用viewWillDisappear
和viewDidDisappear
呢?
因为在iOS4
后引入了后台的概念,当按下Home
键之后,程序被挂起了,但是该View
依然是原来的View
,并不是新的。所以只有内存不够的时候或程序被终止的时候,才会调用viewWillDisappear
和viewDidDisappear
。
在补全两个布局的方法
alloc->initWithNibName->loadView->viewDidLoad->viewWillAppear->viewWillLayoutSubviews->viewDidLayoutSubviews->viewDidAppear->viewWillDisappear->viewDidDisappear->dealloc
方法分析
1.初始化方法:
// 指定初始化方法
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
2.loadView方法
(1)该方法完成了视图控制器的View
的创建
(2)当有特殊需求需要自己创建视图控制器view
时,则重写该方法。此方法是默认的。无特殊要求时不用重写。
(3)当视图控制器的View
将要被使用时,系统自动调用该方法进行创建。
(4)不允许使用super
。当[super loadView]
在方法中时,则不能创建一个View
,则此方法和ViewDidLoad
方法会循环执行,直到程序崩溃。
(5)在loadview
中添加的view
初始化不用必须添加frame
的初值,但是在viewdidload
中是必须添加frame
的初值的,否则页面只能显示不能触发包括点击和输入。
- (void) loadView
{
// 创建登陆界面
LoginView *loginView = [[LoginView alloc] init];
loginView.nameView.textField.delegate = self;
loginView.passWordView.textField.delegate = self;
self.view = loginView;
[loginView release];
}
3.viewDidLoad方法
当loadView
方法执行完成后,view
创建之后立即调用,开发者视图创建和其他操作大部分在此方法中添加。
如果重写方法中代码包含self.view = ???
,即重新为其指定view
时,不需要调用父类实现[super viewDidLoad]
;否则,则需要为调用父类实现。
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
//创建登陆界面
_loginView = [[LoginView alloc] initWithFrame:self.view.bounds];
_loginView.nameView.textField.delegate = self;
_loginView.passWordView.textField.delegate = self;
[self.view addSubview:_loginView];
[_loginView release];
}
4.viewWillAppear和viewDidAppear方法
(1)在View
将要出现和已经出现的时候触发。
(2)layoutSubviews
的方法触发时机在viewWillAppear
和viewDidAppear
方法之间。
(3)viewWillDisappear
和viewDidDisappear
是与其对应的,在 View 销毁时触发的,下面就不举例说明了。
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillDisappear:YES];
//do some thing
}
-(void)viewDidAppear:(BOOL)animated
{
//do some thing
[super viewDidAppear:YES];
}
5.viewWillLayoutSubviews方法
(1)该方法主要进行对视图控制器的 view
以及其子视图进行重新布局。
(2) 在视图控制器的view
将要显示的时候触发。
(3)也就是说,只有在该方法中设置 view
的 frame
才是可行的
(4)viewDidLayoutSubviews
在此方法触发之后触发。
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
self.view.frame = CGRectMake(10, 10, 300, 548);
}
6.didReceiveMemoryWarning方法
(1)当应用可用内存过低导致系统发出内存警告的时候,便会触发此方法。
(2)清除不需要的视图,满足以下两个条件:1.视图已经被创建 2.不需要在 window
上显示了
(3)当从写此方法时,需要调用父类。调用super
的didReceiveMemoryWarning
只是释放controller
的resouse
,不会释放view
。
(4)具体过程:当系统内存不足时,首先UIViewController
的
didReceiveMemoryWarining
方法会被调用,而didReceiveMemoryWarining
会判断当前ViewController
的view
是否显示在window
上,如果没有显示在window
上,则didReceiveMemoryWarining
会自动将viewcontroller
的view
以及其所有子view
全部销毁,然后调用viewcontroller
的viewdidunload
方法。如果当前UIViewController
的view
显示在window
上,则不销毁该viewcontroller
的view
,当然,viewDidunload
也不会被调用了。
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
NSLog(@"@@@@@@@@@@内存警告@@@@@@@@@@");
if ([self isViewLoaded] && !self.view.window) {
self.view = nil;//将视图清除
}
}
7.dealloc 方法
(1)使用ARC的话,dealloc
函数是不需要实现的,写了反而会出错。
(2)有些特殊的情况,dealloc
函数还是需要的。比如,在画面关闭的时候,需要把ViewController
的某些资源释放,在viewDidDissppear
不一定合适,viewDidUnload
一般情况下只在memory warning
的时候才被调用。
MRC
的情况下,我们自然会想到dealloc
函数。
-(void)dealloc
{
NSLog(@"dealloc");
}
loadView && viewDidLoad区别
这两个方法是iphone
开发中不可缺少的,他们都用来初始化视图(而且都是在视图加载的时候调用),但是他们也是又区别的。
简单来说,就是当view
的nib
文件为nil
时,手工创建视图界面时调用loadVIew
;当view
的nib
文件存在的时候,初始化工作在viewDidLoad
中实现。但是如果你的程序运行期间内存不足,视图控制器接到didReceiveMemoryWarning
消息时,那么此时系统默认操作会检查当前视图控制器的view是否还在使用,假如此view
不在当前正在使用的view hierarchy
里面,且控制器实现了loadView
方法,那么这个view
将被release
, loadView
方法将被再次调用来创建一个新的view
。
网友评论