[轉]淺論ViewController的載入 -- 解決 viewDidLoad 被提前載入的問題(pushViewController 前執行)

來源:互聯網
上載者:User

標籤:blog   http   ar   使用   sp   檔案   資料   on   2014   

一個ViewController,一般通過init或initWithNibName來載入。二者沒有什麼不同,init最終還是要調用initWithNibName方法(除非這個ViewController沒有nib檔案)。

我們經常在initWithNibName方法中初始化視圖,變數或者其他成員。這是最常見的initWithNibName方法寫法:

- (id)initWithNibName:(NSString *)nibNameOrNilbundle:(NSBundle *)nibBundleOrNil

{

    self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        label=[[UILabelalloc]initWithFrame:

                  CGRectMake(0,0,160,160)];

        [self.viewaddSubview:label];

...

    }

    returnself;

}

在if語句中,包含了最常見的成員初始化代碼。

在這段代碼中,如果你向ViewController的視圖樹中加入一些新的UIView子類,比如上面的代碼:

[self.viewaddSubview:label];

這不會有什麼問題。但是這會導致另一個方法的調用,即viewDidLoad方法。

viewDidLoad方法一般情況下只會在nib檔案已載入記憶體(即視圖樹構建完成)之後調用。

但還有另一種情況,如果ViewController的view屬性被引用時,view=nil,也會導致nib的載入行為,從而也導致viewDidLoad方法的調用。如果你在initWithNibName方法一直不引用view屬性,則直至initWithNibName方法結束,viewDidLoad方法也不會觸發。

你也許奇怪,如果在代碼中你一直不引用這個ViewController的view屬性怎麼辦?那麼是不是viewDidLoad方法一直都不會調用了?

它會在ViewController對象第1次present時調用,比如你使用presentModalViewController或pushViewController方法彈出它。這兩個方法同時還會調用ViewController的appear方法(即viewWillAppear方法和viewDidAppear方法)。

viewDidLoad方法會比appear方法要早執行(appear方法會導致一個彈齣動畫產生)。而且如果在present之前已經執行過viewDidLoad方法,則present方法不會觸發viewDidLoad方法。

這就是為什麼我們會奇怪viewDidLoad方法中的代碼有時執行有時似乎不被執行的原因。其實根源還是在initWithNibName方法的if語句中。

如果你在initWithNibName時,引用了ViewController的view屬性,由於此時view為nil,將觸發nib檔案的載入行為,導致viewDidLoad方法不等present就提前調用了。由於initWithNibName方法中ViewController成員還未初始化,導致任何對這些成員的引用都是無效的。

比如在viewDidLoad方法中,由於該方法提前執行,導致Data Access Objects還是nil(initWithNibName仍然未執行完)。如果此時在viewDidLoad方法想通過Data Access Objects擷取表格式資料,將得到空。這樣從表面上看,viewDidLoad方法似乎未被執行。

這個情況可以通過兩種方法來改進:

一、initWithNibName方法中,不要有任何成員初始化的代碼。把這些代碼移到viewDidLoad方法開始進行。

二、由於initWithNibName方法保證是在present方法中進行,我們也可以在initWithNibName方法中保留成員初始化代碼。但把原來viewDidLoad方法中的代碼移到appear方法中。也就是,最好不要在viewDidLoad方法中進行和成員初始化無關的事情。這樣還有一個好處,每次presentViewController,都會執行appear方法中的代碼(如果是viewDidLoad方法,則只會在載入nib時執行)。


loadview也是第1次引用ViewController的view屬性(此時,view=nil)時調用,但在viewDidLoad之前。不同的是,loadview在view樹構建前調用,viewDidLoad在view樹構建完成後調用。二者之間,則進行nib的載入。因此,我們常在編程方式建立viewcontroller時重載loadview方法,因為本來就不需要載入nib的內容。

 

轉:http://blog.sina.com.cn/s/blog_947c4a9f01015i23.html

 

[轉]淺論ViewController的載入 -- 解決 viewDidLoad 被提前載入的問題(pushViewController 前執行)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.