生命周期
?我們建立一個(gè)簡(jiǎn)單的模型來測(cè)試生命周期停士,新建兩個(gè)viewController,一個(gè)是主視圖控制器(mainViewController,以下簡(jiǎn)稱mainVC),一個(gè)是副視圖控制器(sub ViewController ,以下簡(jiǎn)稱subVC),在mainVC里點(diǎn)擊一個(gè)button,以modal方式切換至subVC,然后在subVC里點(diǎn)擊另一個(gè)button關(guān)閉subVC涉茧。我們將這兩個(gè)控制器的每個(gè)狀態(tài)都打印出來每界,各個(gè)階段的執(zhí)行如下:
case1.第一次運(yùn)行app:
main loadView
main viewDidLoad
main viewWillAppear
main viewDidAppear
case 2.在mainVC里點(diǎn)擊Button候引,以modal方式切換至subVC:
sub loadView
sub viewDidLoad
main viewWillDisappear
sub viewWillAppear
sub viewDidAppear
main viewDidDisappear
case 3.在subVC里點(diǎn)擊button關(guān)閉subVC并返回mainVC:
sub viewWillDisappear
main viewWillAppear
main viewDidAppear
sub viewDidDisappear
sub dealloc
當(dāng)一個(gè)視圖控制器被創(chuàng)建渊迁,并在屏幕上顯示的時(shí)候代碼的執(zhí)行順序:
step1 ?alloc對(duì)象季研,分配空間
step2飞主,init (initWithNibName)初始化對(duì)象
step3,loadView 從nib載入視圖前鹅,通常這一步不需要去干涉摘悴,除非你沒用使用xib文件創(chuàng)建視圖
step4,viewDidLoad載入完成舰绘,可以進(jìn)行自定義數(shù)據(jù)以及動(dòng)態(tài)創(chuàng)建其他控件
step5蹂喻,viewWillAppear視圖將出現(xiàn)在屏幕之前葱椭,馬上這個(gè)視圖就會(huì)被展現(xiàn)在屏幕上了
step6,viewDidAppear視圖已經(jīng)在屏幕上渲染完成
當(dāng)一個(gè)視圖控制器被移除屏幕并且銷毀的時(shí)候的執(zhí)行順序:
step1 ?viewWillDisappear視圖將從屏幕上移除之前執(zhí)行
step2 ? viewDidDisappear視圖已經(jīng)被從屏幕上移除口四,用戶看不到這個(gè)視圖了
step3 ?dealloc視圖被銷毀
?loadView和viewDidLoad的區(qū)別:當(dāng)loadView時(shí)孵运,還沒有view,而viewDidLoad時(shí)窃祝,view已經(jīng)創(chuàng)建好了掐松。詳細(xì)的加載循環(huán):
step1 ?程序請(qǐng)求viewController的view屬性
step2 ?如果view在內(nèi)存中,則直接加載粪小,如果不存在,則調(diào)用loadView方法
step3 ?loadView方法執(zhí)行如下方法:
* ? 如果重載了這個(gè)方法抡句,則必須創(chuàng)建必要的UIView并且將一個(gè)非nil值傳給ViewController的view屬性
* ? 如果沒用重載這個(gè)方法探膊,viewController會(huì)默認(rèn)使用自己的nibName和nibBundle屬性嘗試從nib文件加載view。如果沒用找到nib文件待榔,它嘗試尋找一個(gè)與viewController類名匹配的nib文件
* ? 如果沒有可用的nib文件逞壁,那么它創(chuàng)建一個(gè)空的UIView作為它的view
最后還要考慮一個(gè)重要的情況:內(nèi)存不足警告。當(dāng)程序員收到內(nèi)存警告的時(shí)候锐锣,會(huì)調(diào)用每一個(gè)ViewController的didReceiveMemoryWarning方法腌闯,我們需要作出響應(yīng),釋放程序中暫時(shí)不需要的資源雕憔,通常都會(huì)重寫該方法姿骏,但記得重寫的時(shí)候要調(diào)用super的該方法。
iOS 3.0-iOS6.0 期間斤彼,didReceiveMemoryWarning方法會(huì)判斷當(dāng)前viewController的viewDidUnload方法分瘦。但是iOS6.0開始,ViewDidUnload和viewWillUnload這兩個(gè)方法已被廢除琉苇,收到lowmemory時(shí)系統(tǒng)不會(huì)釋放view嘲玫,而只是釋放controller的resource。
一種常見處理內(nèi)存警告的方式:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
float ver = [[UIDevice currentDevice] systemVersin] floatValue];
if(ver >= 6.0f)
{
if(self.isViewLoaded && !self.view.window)
{
self.view = nil; // 確保下次重新加載
}
}
}
上面的代碼先取得當(dāng)前iOS系統(tǒng)的版本號(hào)并扇,如果是iOS6.0或以上版本去团,進(jìn)一步判斷視圖是否會(huì)被裝載進(jìn)內(nèi)存,并且是否為當(dāng)前視圖穷蛹,在這兩個(gè)條件都滿足(已經(jīng)裝載進(jìn)內(nèi)存&&不是當(dāng)前視圖)時(shí)土陪,將self.view設(shè)置為nil,這樣就能保證再調(diào)用該viewController時(shí)俩莽,loadView和viewDidLoad被再次調(diào)用旺坠。
我們?cè)趚code調(diào)試器里模擬內(nèi)存警告,監(jiān)控此時(shí)切換的狀態(tài):
case 4扮超, 當(dāng)已切換至subVC取刃,模擬內(nèi)存警告蹋肮,并返回mainVC,不處理didReceiveMomeoryWarning
Received memory warning.
main didReceiveMemoryWarning
sub ? viewWillDisappear
main ?viewWillAppear
main viewDidAppear
sub viewDidDisappear
sub dealloc
case 5.當(dāng)切換至subVC璧疗,模擬內(nèi)存警告坯辩,并返回mainVC,處理didReceiveMemoryWarning崩侠。
main ?didReceiveMemoryWarning
sub didReceiveMemoryWarning
main loadView
main viewDidLoad
sub ?viewWillDisappear
main viewWillAppear
main viewDidAppear
sub viewDidDisappear
sub dealloc
可以看出漆魔,當(dāng)處理了didReceivememoryWarning后,重新執(zhí)行了非當(dāng)前視圖的loadView和viewDidLoad方法却音。