當(dāng)系統(tǒng)遭遇內(nèi)存警告的時(shí)候浓冒,會(huì)調(diào)用VC的下述函數(shù)衙吩,在該函數(shù)內(nèi)存笔刹,我們可以釋放一些能夠再次被創(chuàng)建的資源芥备,比如維持的從網(wǎng)絡(luò)或者數(shù)據(jù)庫(kù)來(lái)的數(shù)據(jù)等等。 ~~~
(void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } ~~~
視圖管理流程
先來(lái)看一張比較大的圖舌菜,這是apple目前提供的和View控制相關(guān)的一些函數(shù)的摘錄(UIViewController中的函數(shù)).而這也是一個(gè)調(diào)用的時(shí)序關(guān)系圖萌壳。VC的view還有其子View的創(chuàng)建使用,都在這個(gè)流程之中日月。
流程解釋
創(chuàng)建根視圖
當(dāng)VC.view為空的時(shí)候袱瓮,并且第一次調(diào)用vc.view的時(shí)候,會(huì)調(diào)用loadView函數(shù)來(lái)加載跟視圖爱咬。
- (void) loadView
{
self.view = [UIViewnew];
}
在這個(gè)函數(shù)中你可以使用self.view = **來(lái)對(duì)根視圖進(jìn)行賦值尺借,而且建議也是只在這里進(jìn)行根視圖的賦值操作。因?yàn)橐坏└晥D確定后精拟,外部會(huì)對(duì)根視圖進(jìn)行一些布局了之類的操作燎斩,如果在使用過(guò)程中隨意的更換根視圖,上述的這些操作將很難重放蜂绎。導(dǎo)致界面的一些異常栅表。
初始化根視圖上子視圖
當(dāng)調(diào)用了loadView加載了根視圖之后,系統(tǒng)會(huì)觸發(fā)VC的ViewDidLoad函數(shù)荡碾。這個(gè)使用self.view已經(jīng)有值谨读,可以在其上addSubView了。
在這里我們一般會(huì)做一些處理初始化子視圖坛吁,并且addSubView之類的操作劳殖。注意布局的事情,就不要在這里做了拨脉,因?yàn)橄到y(tǒng)為我們提供了專門的函數(shù)來(lái)做這個(gè)事情哆姻。而且這個(gè)地方你拿到的self.view的frame信息是不準(zhǔn)確的。比如剛才我們?cè)趌oadView中沒(méi)有對(duì)view進(jìn)行布局初始化玫膀,給他設(shè)置一個(gè)frame矛缨。到了這個(gè)ViewDidLoad的地方的時(shí)候,你拿到的self.view.frame就是{0,0,0,0}帖旨。也就是說(shuō)箕昭,你在這里進(jìn)行布局的話,非常有可能是亂的解阅。
- (void)viewDidLoad {
[superviewDidLoad];
_subView = [DZViewnew];
_subView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_subView];
}
布局
一般情況下落竹,對(duì)于VC的根視圖的操作是外部進(jìn)行的,比如UINavigationController去push一個(gè)VC的時(shí)候货抄,就會(huì)對(duì)vc.view.frame進(jìn)行賦值述召,來(lái)控制VC的布局朱转。而系統(tǒng)的這些試圖控制器(導(dǎo)航了,之類的東西)积暖,都實(shí)現(xiàn)了CALayer的delegate藤为,當(dāng)vc的根視圖的frame發(fā)生變化的時(shí)候會(huì)接受到通知
- layoutSublayersOfLayer:
系統(tǒng)的視圖控制器會(huì)在這里面調(diào)用這兩個(gè)函數(shù)來(lái)通知其當(dāng)前的子VC去做布局的工作:
- viewWillLayoutSubviews
- viewDidLayoutSubviews
而這個(gè)子VC一般是我們創(chuàng)建的。在這兩個(gè)函數(shù)里面我們?nèi)プ霾季值牟僮鞫嵝獭_@兩個(gè)函數(shù)一個(gè)是在view本身的布局做完之前調(diào)用缅疟,一個(gè)是之后。無(wú)論哪個(gè)函數(shù)性誉,這里面渠道的根視圖的frame或者bounds信息都是準(zhǔn)確的窿吩。
而且,如果在這兩個(gè)函數(shù)里面進(jìn)行相對(duì)布局操作的話错览,將會(huì)讓VC的根視圖擁有適配不同屏幕的能力纫雁,同時(shí)當(dāng)調(diào)整根視圖的frame的時(shí)候,整個(gè)視圖的布局也能夠作出相應(yīng)的變化倾哺。
顯示流程
- viewWillAppear:
– viewDidAppear:
- viewWillDisappear:
- viewDidDisappear:
從上述函數(shù)的字面意思理解:當(dāng)視圖被加載之后轧邪,要在window上顯示出來(lái),處于用戶可見(jiàn)區(qū)域羞海,或者離開(kāi)用戶可見(jiàn)區(qū)域的時(shí)候忌愚。系統(tǒng)將會(huì)調(diào)用VC相關(guān)函數(shù)來(lái)通知這種變化。
我們?nèi)タ磛iewWillDisappear的文檔:
This method is called in response to a view being removed from a view hierarchy. This method is called before the view is actually removed and before any animations are configured.
而上述顯示流程能夠被觸發(fā)是依賴系統(tǒng)的這套機(jī)制的:
而現(xiàn)在系統(tǒng)集中默認(rèn)的試圖管理器UINavitionController却邓,UITabBarController,還有present方式硕糊,都是可以保證會(huì)使用上述機(jī)制來(lái)觸發(fā)響應(yīng)的顯示邏輯的。在這些函數(shù)里面腊徙,我們可以做一些和顯示相關(guān)的業(yè)務(wù)邏輯了简十。
但是當(dāng)你做業(yè)務(wù)邏輯的時(shí)候,一定要考慮這個(gè)函數(shù)在整個(gè)流程中的時(shí)序關(guān)系和他所代表的涵義撬腾。尤其是在每個(gè)視圖管理器中的控制流程中螟蝙,比如最開(kāi)始提到的去獲取self.navigationController為空的問(wèn)題。
總結(jié)
關(guān)于ViewController的關(guān)鍵的流程民傻,先視圖管理這個(gè)胰默。當(dāng)然其還有其他的一些流程,要說(shuō)完有點(diǎn)太復(fù)雜了漓踢。希望通過(guò)上述的兩個(gè)例子牵署,能夠展示一下流程建模在理解框架和使用框架上的一些的裨益。能夠使用這種思想來(lái)思考日常的編程問(wèn)題喧半。