UIview 與 UIviewController 不得不說的"事"

weixin_33670713發表於2017-03-24

一.   Controller 和 View 的定義

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

UIview : 檢視.用來展示介面. 

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

二.   Controller和View的生命週期

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

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


2491655-f507e043f3e3bc69.jpeg

從圖中可知.當我們建立一個Controller的時候,alloc 告訴記憶體,給我一塊地,我要用,當這塊地審批過後,我們就用init 方法,來搭建我們要蓋的小房子,此時的相框就搭建好了,但是我們的畫布可並沒有建立,當然 Controller 是要建立自己的畫布的,不然怎麼展示美美的自己呢, Controller 想了一下,那我就用lazyinit方式建立吧,畢竟其他的我也不會,哈哈 .一不小心就說漏嘴了>>>>>>

這樣我們就知道,我們呼叫的view 屬性的getter方法:[self view]. 知道getter方法的原理的我們可以知道,在getter裡面會先判斷view 是否建立,如果沒有建立,那麼我們就去建立,但是此時view的建立和我們想的不一樣,它是通過呼叫loadView 來建立view的.

loadView 

1 . 什麼時候被呼叫

每次訪問UIViewController的view(比如controller.view、self.view)而且view為nil,loadView方法就會被呼叫.

2 . 有什麼作用

loadView方法是用來負責建立UIViewController的view.

3 . 預設實現的方式是怎樣呢?

    預設實現即[super loadView] 但是在這裡又做了什麼事呢

   1>    它會先去查詢是否使用xib檔案來建立Controller ,如果是,通過載入xib檔案來建立UIViewController的View 

         如果在初始化UIViewController 指定了XIB檔名,就會根據傳入的XIB檔案載入對應的xib檔案

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

        如果沒有明顯地傳入XIB檔名,就會載入跟UIViewController 同名的XIB檔案

        [[FTTViewController alloc]init];

2>    如果沒有找到相關聯的xib檔案,就會建立一個空白的UIView,然後賦值個UIViewController的view 

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

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

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

大家都知道UIViewController的view可以通過xib檔案來建立,但是在某些情況下,xib不是那麼地靈活,所以有時候我們想通過程式碼來建立UIView,比如:

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

如果想通過程式碼來建立UIViewController的view,就要重寫loadView方法,並且不需要呼叫[super loadView],因為在第3點裡面已經提到:若沒有xib檔案,[super loadView]預設會建立一個空白的UIView。我們既然要通過程式碼來自定義UIView,那麼就沒必要事先建立一個空白的UIView,以節省不必要的開銷。正確的做法應該是這樣:

- (void)loadView {

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

}

不需要呼叫[super loadView],你呼叫了也不會出錯,只是造成了一些不必要的開銷。

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

viewDidLoad

1.什麼時候被呼叫?

不過你是通過xib檔案還是重寫loadView建立UIViewController的view,在view建立完畢後,最終都會呼叫viewDidLoad方法

2.有什麼作用?

一般我們會在這裡做介面上的初始化操作,比如往view中新增一些子檢視、從資料庫或者網路載入模型資料裝配到子檢視中。

- (void)viewDidLoad {

      [super viewDidLoad];

      [self.view addSubview:self.btn];

}

viewWillAppear

這個一般在view被新增到superview之前,切換動畫之前呼叫。在這裡可以進行一些顯示前的處理。比如鍵盤彈出,一些特殊的過程動畫(比如狀態條和navigationbar顏色)

viewDidAppear

一般用於顯示後,在切換動畫後,如果有需要的操作,可以在這裡加入相關程式碼

viewDidUnload

1.什麼時候被呼叫?

iOS裝置的記憶體是極其有限的,如果應用程式佔用的記憶體過多的話,系統就會對應用程式發出記憶體警告。UIViewController就會收到didReceiveMemoryWarning訊息。didReceiveMemoryWarning方法的預設實現是:如果當前UIViewController的view不在應用程式的檢視層次結構(View Hierarchy)中,即view的superview為nil的時候,就會將view釋放,並且呼叫viewDidUnload方法

2.有什麼作用?

上面說到,發出記憶體警告且view被釋放的時候就會呼叫viewDidUnload方法,所以一般在釋放資源,主要是釋放介面元素相關的資源,將相關的例項都賦值為nil

- (void)viewDidUnload {

       [super viewDidUnload];

       self.name = nil;

       self.pwd = nil;

}

3.dealloc也是用來釋放資源的,那跟viewDidUnload有什麼關係?

當發出記憶體警告呼叫viewDidUnload方法時,只是釋放了view,並沒有釋放UIViewController,所以並不會呼叫dealloc方法。即viewDidUnload和dealloc方法並沒有任何關係,dealloc方法只會在UIViewController被釋放的時候呼叫


loadView、viewDidLoad及viewDidUnload的關係

1.第一次訪問UIViewController的view時,view為nil,然後就會呼叫loadView方法建立view

2.view建立完畢後會呼叫viewDidLoad方法進行介面元素的初始化

3.當記憶體警告時,系統可能會釋放UIViewController的view,將view賦值為nil,並且呼叫viewDidUnload方法

4.當再次訪問UIViewController的view時,view已經在3中被賦值為nil,所以又會呼叫loadView方法重新建立view

5.view被重新建立完畢後,還是會呼叫viewDidLoad方法進行介面元素的初始化

參考文章

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

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

相關文章