UIview 與 UIviewController 不得不說的"事"

一. ? Controller 和 View 的定義

UIviewController: 視圖控制器.從名字我可以知道它是一個控制器并且是控制視圖的.?

UIview : 視圖.用來展示界面.?

簡單的說就是UIViewController就是一個相框 ,而UIView 就相當(dāng)于相片,相框可以隨時隨地的 拿走這個相片而換另外一張相片,或者在這張相片上加一個新的相片.從而我們就可以知道相片是不能操作相框的.視圖控制器 管理 視圖 的生命周期.

二. ? Controller和View的生命周期

這里我先說說Controller自帶的view,它作為Controller的屬性,view生命周期是在Controller的生命周期里面的. 簡單點,說話的方式簡單點 , 哈哈 ,這樣Controller 就不能在view釋放前釋放.

盜圖一張 ?哈哈哈 ?圖講的很詳細.比我說更有說服力.


從圖中可知.當(dāng)我們創(chuàng)建一個Controller的時候,alloc 告訴內(nèi)存,給我一塊地,我要用,當(dāng)這塊地審批過后,我們就用init 方法,來搭建我們要蓋的小房子,此時的相框就搭建好了,但是我們的畫布可并沒有創(chuàng)建,當(dāng)然 Controller 是要創(chuàng)建自己的畫布的,不然怎么展示美美的自己呢, Controller 想了一下,那我就用lazyinit方式創(chuàng)建吧,畢竟其他的我也不會,哈哈 .一不小心就說漏嘴了>>>>>>

這樣我們就知道,我們調(diào)用的view 屬性的getter方法:[self view]. 知道getter方法的原理的我們可以知道,在getter里面會先判斷view 是否創(chuàng)建,如果沒有創(chuàng)建,那么我們就去創(chuàng)建,但是此時view的創(chuàng)建和我們想的不一樣,它是通過調(diào)用loadView 來創(chuàng)建view的.

loadView?

1 . 什么時候被調(diào)用

每次訪問UIViewController的view(比如controller.view、self.view)而且view為nil,loadView方法就會被調(diào)用.

2 . 有什么作用

loadView方法是用來負責(zé)創(chuàng)建UIViewController的view.

3 . 默認實現(xiàn)的方式是怎樣呢?

? ? 默認實現(xiàn)即[super loadView] 但是在這里又做了什么事呢

? ?1> ? ?它會先去查找是否使用xib文件來創(chuàng)建Controller ,如果是,通過加載xib文件來創(chuàng)建UIViewController的View?

? ? ? ? ?如果在初始化UIViewController 指定了XIB文件名,就會根據(jù)傳入的XIB文件加載對應(yīng)的xib文件

? ? ? ? [[FTTViewController alloc] initWithNibName:@"FTViewController" bundle:nil];

? ? ? ? 如果沒有明顯地傳入XIB文件名,就會加載跟UIViewController 同名的XIB文件

? ? ? ? [[FTTViewController alloc]init];

2> ? ?如果沒有找到相關(guān)聯(lián)的xib文件,就會創(chuàng)建一個空白的UIView,然后賦值個UIViewController的view?

self.view = [[UIView alloc]initWithFrame:[[UIScreen mainScreen].applicationFrame]];

// applicationFrame的值是:{{x = 0, y = 20}

4 怎么正確使用這個方法?

大家都知道UIViewController的view可以通過xib文件來創(chuàng)建,但是在某些情況下,xib不是那么地靈活,所以有時候我們想通過代碼來創(chuàng)建UIView,比如:

self.view = [[[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] ];

如果想通過代碼來創(chuàng)建UIViewController的view,就要重寫loadView方法,并且不需要調(diào)用[super loadView],因為在第3點里面已經(jīng)提到:若沒有xib文件,[super loadView]默認會創(chuàng)建一個空白的UIView。我們既然要通過代碼來自定義UIView,那么就沒必要事先創(chuàng)建一個空白的UIView,以節(jié)省不必要的開銷。正確的做法應(yīng)該是這樣:

- (void)loadView {

self.view = [[[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] ];

}

不需要調(diào)用[super loadView],你調(diào)用了也不會出錯,只是造成了一些不必要的開銷。

總結(jié)一句話,蘋果設(shè)計這個方法就是給我們自定義UIViewController的view用的

viewDidLoad

1.什么時候被調(diào)用?

不過你是通過xib文件還是重寫loadView創(chuàng)建UIViewController的view,在view創(chuàng)建完畢后,最終都會調(diào)用viewDidLoad方法

2.有什么作用?

一般我們會在這里做界面上的初始化操作,比如往view中添加一些子視圖、從數(shù)據(jù)庫或者網(wǎng)絡(luò)加載模型數(shù)據(jù)裝配到子視圖中。

- (void)viewDidLoad {

? ? ? [super viewDidLoad];

? ? ? [self.view addSubview:self.btn];

}

viewWillAppear

這個一般在view被添加到superview之前,切換動畫之前調(diào)用。在這里可以進行一些顯示前的處理。比如鍵盤彈出,一些特殊的過程動畫(比如狀態(tài)條和navigationbar顏色)

viewDidAppear

一般用于顯示后,在切換動畫后,如果有需要的操作,可以在這里加入相關(guān)代碼

viewDidUnload

1.什么時候被調(diào)用?

iOS設(shè)備的內(nèi)存是極其有限的,如果應(yīng)用程序占用的內(nèi)存過多的話,系統(tǒng)就會對應(yīng)用程序發(fā)出內(nèi)存警告。UIViewController就會收到didReceiveMemoryWarning消息。didReceiveMemoryWarning方法的默認實現(xiàn)是:如果當(dāng)前UIViewController的view不在應(yīng)用程序的視圖層次結(jié)構(gòu)(View Hierarchy)中,即view的superview為nil的時候,就會將view釋放,并且調(diào)用viewDidUnload方法

2.有什么作用?

上面說到,發(fā)出內(nèi)存警告且view被釋放的時候就會調(diào)用viewDidUnload方法,所以一般在釋放資源,主要是釋放界面元素相關(guān)的資源,將相關(guān)的實例都賦值為nil

- (void)viewDidUnload {

? ? ? ?[super viewDidUnload];

? ? ? ?self.name = nil;

? ? ? ?self.pwd = nil;

}

3.dealloc也是用來釋放資源的,那跟viewDidUnload有什么關(guān)系?

當(dāng)發(fā)出內(nèi)存警告調(diào)用viewDidUnload方法時,只是釋放了view,并沒有釋放UIViewController,所以并不會調(diào)用dealloc方法。即viewDidUnload和dealloc方法并沒有任何關(guān)系,dealloc方法只會在UIViewController被釋放的時候調(diào)用


loadView、viewDidLoad及viewDidUnload的關(guān)系

1.第一次訪問UIViewController的view時,view為nil,然后就會調(diào)用loadView方法創(chuàng)建view

2.view創(chuàng)建完畢后會調(diào)用viewDidLoad方法進行界面元素的初始化

3.當(dāng)內(nèi)存警告時,系統(tǒng)可能會釋放UIViewController的view,將view賦值為nil,并且調(diào)用viewDidUnload方法

4.當(dāng)再次訪問UIViewController的view時,view已經(jīng)在3中被賦值為nil,所以又會調(diào)用loadView方法重新創(chuàng)建view

5.view被重新創(chuàng)建完畢后,還是會調(diào)用viewDidLoad方法進行界面元素的初始化

參考文章

http://blog.csdn.net/q199109106q/article/details/8614044

blog.csdn.net/qijianli/article/details/7826979/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容