view的加載流程

loadView的用法

轉自:http://haoxiang.org/page/5/

 

UIViewController的loadView

用UIViewController有一段時間了,才發現以前對loadView的理解完全不到位。

假如我們用Xcode新建一個View-based Application,在ViewController.m中加上

- (void) loadView {
NSLog(@"loadView Called");
}

再增加viewDidLoad,按照一般的情況,我們會有這樣的Code

- (void) viewDidLoad {
[super viewDidLoad];
UIButton *customButton = [UIButton buttonWith.....
......
[self.view addSubView:customButton];
}

現在打開MainWindow.xib,刪掉其中的ViewController,並在AppDelegate.m的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

裏增加ViewController的初始化

viewController = [[XXXViewController alloc] init];

編譯運行就有問題了。Console中不斷的輸出loadView Called!

仔細的閱讀loadView的文檔,才知道loadView不是這麼用的。

loadView在每一次使用self.view這個property,並且self.view爲nil的時候被調用,用以產生一個有效的self.view。這個接口原本是爲了讓我們自定義view用的。在不被subclass實現的情況下,也就是[super loadView]的效果,應該就是產生了一個有效的view,也就是一個空白的view。

在上面這種情況下,loadView被實現爲空(只有一條打印語句),而且我們沒有通過XIB初始化ViewController,所以在viewDidLoad被執行時,self.view是爲nil的。所以在執行[self.view addSubView:customButton]時,loadView被調用,用來產生一個有效的view,使得self.view不再爲nil。罷特,我們錯了(-_-!)。我們的loadView什麼也沒有做,於是就出現了上面的情形,不斷的調用一個什麼都不做的loadView….

當然,我們只要在loadView中增加一句[super loadView]就沒有問題了。但這並不是Cocoa的設計者所期望的。

loadView僅僅應該在開發者希望自行通過編碼而不是Interface Builder定製view的時候被實現,而且不應該在其中調用[super loadView],你的loadView中應該有self.view = …這樣的行爲。

如果僅僅是想要在當前view上增加一些UIButton或是UILabel,應該在viewDidLoad裏去做,此時不要實現自己的loadView。

 

 

 

 

 

轉自:http://www.cocoachina.com/bbs/simple/?t52059.html

loadView VS viewDidLoad

loadView 和 viewDidLoad 的區別

iPhone開發必不可少的要用到這兩個方法
 他們都可以用來在視圖載入的時候,初始化一些內容 但是他們有什麼區別呢?
viewDidLoad 此方法在view被  addsubWiew後調用viewDidLoad用於初始化,加載時用到的。 (不論是從xib中加載視圖,還是從loadview生成視圖,都會被調用。)
loadView 此方法在控制器的view爲nil的時候被調用。 此方法用於以編程的方式創建view的時候用到。loadView是使用代碼生成視圖的時候,當視圖第一次載入的時候調用的方法。用於使用(寫)代碼來實現控件。用於使用代碼生成控件的函數。如: 
( void ) loadView { 
    UIView *view = [ [ UIView alloc] initWithFrame:[ UIScreen 
mainScreen] .applicationFrame] ; 
[ view setBackgroundColor:_color] ; 
    self.view = view; 
[ view release] ; 
} 


你在控制器中實現了loadView方法,那麼你可能會在應用運行的某個時候被內存管理控制調用。 如果設備內存不足的時候, view 控制器會收到didReceiveMemoryWarning的消息。 默認的實現是檢查當前控制器的view是否在使用。如果它的view不在當前正在使用的view hierarchy裏面,且你的控制器實現了loadView方法,那麼這個view將被release, loadView方法將被再次調用來創建一個新的view。 

 UIViewController 的內存管理
在 iOS3.0 後,UIViewController 多了一個叫做 viewDidUnLoad 的方法。
   先看下 UIViewController 從創建 view 到展示的流程的幾個函數

    -init
    -initWithNibName:bundle:

這兩個方法都是初始化一個 vc,但請注意 view 不是這時候載入的

    -loadView
    -viewDidLoad

    當一個視圖準備展現時,vc 首先會判斷 view 是否已經創建否則便通過之前指定的 xib 文件來初始化 view,以及綁定其他關係(若沒有指定 xib 文件,則默認會搜索和 vc 同名的 xib,比如 myNameViewController 就會搜索 myNameViewController.xib 文件)

    若是沒有 xib 文件,你就可以在 loadview 中自己手動創建這個 viewControoler 需要的視圖。接下來就是調用到 -viewDidLoad,許多人喜歡在這裏做些其他事情,比如做個 http 請求、建立個數組啥的。這裏若不處理正確,-viewDidUnload 激活時內存就容易泄露了,稍後提到。

    -view()appear
    -view()disappear

    這幾個方法就不解釋了

    -viewDidUnload

    該方法在收到內存警告,同時該視圖並不在當前界面顯示時候會被調用,此時該 controller 的 view 已經被釋放並賦值爲 nil。
接下來你要做的是

把實例變量的子視圖釋放(IBOulet 的,以及自己添加的)
其他實例變量,比如之前在 -viewDidLoaded 中實例的數據數組、http 請求釋放掉
    因爲當該 viewController 再次被激活準備顯示時(比如 navigationControler 返回到上一級),vc 發現自己的 view 爲空後會重複之前的流程直到把 view 給創建起來。若沒將自己額外添加的子視圖,各種類實例變量釋放,這裏便會重新再次創建。

    於是,內存泄露了。

 

 

注意iphone開發中的這兩個函數viewWillAppear和viewDidAppear
每當視圖準備在屏幕上顯示,或者視圖已在屏幕上完全顯示時,將調用這兩個方法。

viewWillAppear:方法更新準備顯示的視圖的信息。調用時,視圖可能還沒有被加載。
使用viewDidAppear:來觸發視圖完全顯示在屏幕上之後的行爲,例如任何動畫。
viewdidload是當程序第一次加載view時調用,以後都不會用到,而viewDidAppear是每當切換到view時就調用。

loadView和viewDidLoad方法。假設不使用xib文件對視圖佈局,那麼loadView方法必須設置屏幕,並對任何子視圖佈局。每當繼承一個具體的子類,例如UITableViewController或UITabBarController時,務必調用[super  loadView]或者實現viewDidLoad。這樣一來,在進行定製之前,父類可以對屏幕進行適當的設置。當代碼基於具體的子類時,蘋果的文檔和示例代碼鼓勵使用viewDidLoad。
viewDidLoad 此方法只有當view從nib文件初始化的時候才被調用viewDidLoad用於初始化,加載時用到的。
loadView 此方法在控制器的view爲nil的時候被調用。 此方法用於以編程的方式創建view的時候用到。loadView是使用代碼生成視圖的時候,當視圖第一次載入的時候調用的方法。用於使用(寫)代碼來實現控件。用於使用代碼生成控件的函數。

viewDidLoad ,不論是從xib中加載視圖,還是從loadview生成視圖,都會被調用。


另官方文檔裏關於 load cycleunload cycle圖示
圖片
圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章