標籤: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 前執行)