ViewController
是iOS
開發(fā)中MVC
模式中的C
嗡午,ViewController
是view
的Controller
吴裤,ViewController
的職責(zé)主要包括管理內(nèi)部各個(gè)view
的加載顯示和卸載售躁,同時(shí)負(fù)責(zé)與其他ViewController
的通信和協(xié)調(diào)。
分類
在iOS中,有兩類ViewController
,一類是顯示內(nèi)容的辽剧,比如UIViewController
、UITableViewController
等税产,同時(shí)還可以自定義繼承自UIViewController
怕轿;另一類是ViewController
容器,UINavigationController
和UITabBarController
等辟拷,UINavigationController
是以Stack
的形式來存儲(chǔ)和管理ViewController
撞羽,UITabBarController
是以Array
的形式來管理ViewController
。
加載過程
在Controller
中創(chuàng)建View
有兩種方法衫冻,一種是使用Storyboard
等可視化工具诀紊,另一種是通過代碼創(chuàng)建。
可視化工具在開發(fā)中方便快捷隅俘,但是流暢性不如純代碼的方式創(chuàng)建邻奠。
ViewController生命周期
alloc->initWithNibName->loadView->viewDidLoad->viewWillAppear->viewDidAppear->viewWillDisappear->viewDidDisappear->dealloc
注意viewWillUnload
和viewDidUnload
已經(jīng)在iOS6
被廢棄了,因?yàn)?code>Clearing references to views is no longer necessary.
注意:沒有viewWillLoad
注意:viewDidLoad
和viewDidUnload
并不是成對(duì)的为居。
程序運(yùn)行中按下Home
鍵碌宴,程序并沒有以上方法的觸發(fā),但雙擊Home
鍵蒙畴,刪除該程序?qū)?huì)觸發(fā)贰镣,View Will Disappear
和View Did Disappear
兩個(gè)方法。
為什么按下Home
鍵之后沒有調(diào)用viewWillDisappear
和viewDidDisappear
呢膳凝?
因?yàn)樵?code>iOS4后引入了后臺(tái)的概念八孝,當(dāng)按下Home
鍵之后,程序被掛起了鸠项,但是該View
依然是原來的View
干跛,并不是新的。所以只有內(nèi)存不夠的時(shí)候或程序被終止的時(shí)候祟绊,才會(huì)調(diào)用viewWillDisappear
和viewDidDisappear
楼入。
在補(bǔ)全兩個(gè)布局的方法
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
的創(chuàng)建
(2)當(dāng)有特殊需求需要自己創(chuàng)建視圖控制器view
時(shí)哥捕,則重寫該方法。此方法是默認(rèn)的嘉熊。無(wú)特殊要求時(shí)不用重寫遥赚。
(3)當(dāng)視圖控制器的View
將要被使用時(shí),系統(tǒng)自動(dòng)調(diào)用該方法進(jìn)行創(chuàng)建阐肤。
(4)不允許使用super
凫佛。當(dāng)[super loadView]
在方法中時(shí),則不能創(chuàng)建一個(gè)View
孕惜,則此方法和ViewDidLoad
方法會(huì)循環(huán)執(zhí)行愧薛,直到程序崩潰。
(5)在loadview
中添加的view
初始化不用必須添加frame
的初值衫画,但是在viewdidload
中是必須添加frame
的初值的毫炉,否則頁(yè)面只能顯示不能觸發(fā)包括點(diǎn)擊和輸入。
- (void) loadView
{
// 創(chuàng)建登陸界面
LoginView *loginView = [[LoginView alloc] init];
loginView.nameView.textField.delegate = self;
loginView.passWordView.textField.delegate = self;
self.view = loginView;
[loginView release];
}
3.viewDidLoad方法
當(dāng)loadView
方法執(zhí)行完成后削罩,view
創(chuàng)建之后立即調(diào)用瞄勾,開發(fā)者視圖創(chuàng)建和其他操作大部分在此方法中添加。
如果重寫方法中代碼包含self.view = 弥激?进陡??
微服,即重新為其指定view
時(shí)四濒,不需要調(diào)用父類實(shí)現(xiàn)[super viewDidLoad]
;否則,則需要為調(diào)用父類實(shí)現(xiàn)职辨。
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
//創(chuàng)建登陸界面
_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
將要出現(xiàn)和已經(jīng)出現(xiàn)的時(shí)候觸發(fā)盗蟆。
(2)layoutSubviews
的方法觸發(fā)時(shí)機(jī)在viewWillAppear
和viewDidAppear
方法之間。
(3)viewWillDisappear
和viewDidDisappear
是與其對(duì)應(yīng)的,在 View 銷毀時(shí)觸發(fā)的,下面就不舉例說明了舒裤。
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillDisappear:YES];
//do some thing
}
-(void)viewDidAppear:(BOOL)animated
{
//do some thing
[super viewDidAppear:YES];
}
5.viewWillLayoutSubviews方法
(1)該方法主要進(jìn)行對(duì)視圖控制器的 view
以及其子視圖進(jìn)行重新布局喳资。
(2) 在視圖控制器的view
將要顯示的時(shí)候觸發(fā)。
(3)也就是說,只有在該方法中設(shè)置 view
的 frame
才是可行的
(4)viewDidLayoutSubviews
在此方法觸發(fā)之后觸發(fā)腾供。
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
self.view.frame = CGRectMake(10, 10, 300, 548);
}
6.didReceiveMemoryWarning方法
(1)當(dāng)應(yīng)用可用內(nèi)存過低導(dǎo)致系統(tǒng)發(fā)出內(nèi)存警告的時(shí)候,便會(huì)觸發(fā)此方法仆邓。
(2)清除不需要的視圖,滿足以下兩個(gè)條件:1.視圖已經(jīng)被創(chuàng)建 2.不需要在 window
上顯示了
(3)當(dāng)從寫此方法時(shí),需要調(diào)用父類。調(diào)用super
的didReceiveMemoryWarning
只是釋放controller
的resouse
伴鳖,不會(huì)釋放view
节值。
(4)具體過程:當(dāng)系統(tǒng)內(nèi)存不足時(shí),首先UIViewController
的
didReceiveMemoryWarining
方法會(huì)被調(diào)用榜聂,而didReceiveMemoryWarining
會(huì)判斷當(dāng)前ViewController
的view
是否顯示在window
上搞疗,如果沒有顯示在window
上,則didReceiveMemoryWarining
會(huì)自動(dòng)將viewcontroller
的view
以及其所有子view
全部銷毀须肆,然后調(diào)用viewcontroller
的viewdidunload
方法匿乃。如果當(dāng)前UIViewController
的view
顯示在window
上桩皿,則不銷毀該viewcontroller
的view
,當(dāng)然幢炸,viewDidunload
也不會(huì)被調(diào)用了泄隔。
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
NSLog(@"@@@@@@@@@@內(nèi)存警告@@@@@@@@@@");
if ([self isViewLoaded] && !self.view.window) {
self.view = nil;//將視圖清除
}
}
7.dealloc 方法
(1)使用ARC的話,dealloc
函數(shù)是不需要實(shí)現(xiàn)的宛徊,寫了反而會(huì)出錯(cuò)佛嬉。
(2)有些特殊的情況,dealloc
函數(shù)還是需要的闸天。比如暖呕,在畫面關(guān)閉的時(shí)候,需要把ViewController
的某些資源釋放号枕,在viewDidDissppear
不一定合適缰揪,viewDidUnload
一般情況下只在memory warning
的時(shí)候才被調(diào)用陨享。
MRC
的情況下葱淳,我們自然會(huì)想到dealloc
函數(shù)。
-(void)dealloc
{
NSLog(@"dealloc");
}
loadView && viewDidLoad區(qū)別
這兩個(gè)方法是iphone
開發(fā)中不可缺少的抛姑,他們都用來初始化視圖(而且都是在視圖加載的時(shí)候調(diào)用)赞厕,但是他們也是又區(qū)別的。
簡(jiǎn)單來說定硝,就是當(dāng)view
的nib
文件為nil
時(shí)皿桑,手工創(chuàng)建視圖界面時(shí)調(diào)用loadVIew
;當(dāng)view
的nib
文件存在的時(shí)候蔬啡,初始化工作在viewDidLoad
中實(shí)現(xiàn)诲侮。但是如果你的程序運(yùn)行期間內(nèi)存不足,視圖控制器接到didReceiveMemoryWarning
消息時(shí)箱蟆,那么此時(shí)系統(tǒng)默認(rèn)操作會(huì)檢查當(dāng)前視圖控制器的view是否還在使用沟绪,假如此view
不在當(dāng)前正在使用的view hierarchy
里面,且控制器實(shí)現(xiàn)了loadView
方法空猜,那么這個(gè)view
將被release
, loadView
方法將被再次調(diào)用來創(chuàng)建一個(gè)新的view
绽慈。