2012-01-16 58 views
23

當我編程,沒有一個筆尖,我的印象是,我需要調用的loadView初始化我認爲,像這樣下:正確使用的loadView和viewDidLoad中使用的UIViewController無碎粒/ xibs

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nil bundle:nil]; 
    if (self) { 
     // Custom initialization 
     [self loadView]; 
    } 
    return self; 
} 

(我。已設置nibNameOrNil =零,因爲沒有筆尖)

然後,我設置的觀點,這樣的:

- (void) loadView { 
    self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 367)]; 
    [self viewDidLoad]; 
} 

這是盡一切viewDidLoad中其他。

我仍然不確定是否應該以這種方式調用loadView和viewDidLoad。他們沒有自動調用。

什麼是混淆是對UIViewController類引用文檔中:

的loadView討論

你永遠不應該直接調用此方法。視圖控制器在請求視圖屬性時調用 此方法,但當前爲零。 如果您手動創建視圖,則必須覆蓋此方法,並使用它來創建視圖。如果使用Interface Builder創建視圖並初始化視圖控制器,即使用initWithNibName:bundle:方法初始化視圖 視圖,請直接設置nibName和 nibBundle屬性,或者同時創建視圖和視圖 控制器在界面生成器中 - 那麼你不能重寫這個 方法。

所以,我不明白如果我不應該直接調用它,如何調用loadView。

此方法的默認實現查找有效的筆尖 信息並使用該信息加載關聯的筆尖文件。 如果未指定nib信息,則默認實現會創建一個普通的UIView對象並將其設置爲主視圖。

我不明白這是如何工作的 - 創建一個痛苦UIView。

如果重寫此方法,以手動創建你的意見,你 應該這樣做並分配層次的根視圖到 視圖屬性。 (您創建的視圖應該是唯一的實例,並且不應該與其他視圖控制器對象共享 )。

如果您想對視圖執行任何額外的初始化,請在viewDidLoad方法中執行 。在iOS 3.0及更高版本中,您還應該使用 覆蓋viewDidUnload方法,以釋放對該視圖或其內容的任何引用。

好吧,到目前爲止它沒有說如何調用viewDidLoad。因此,對於viewDidLoad中:

viewDidLoad中討論

視圖控制器加載其 關聯的視圖到存儲器後,此方法被稱爲無論視圖是存儲在nib文件中,還是以編程方式在loadView方法中創建 ,無論是 ,都會調用此方法。此方法通常用於對從nib文件加載的視圖執行其他初始化步驟 。

叫什麼?

由於這些方法沒有在我的代碼中自動調用,我只能認爲我必須自己調用它們。但是我仍然沒有從文檔中清楚地理解這是正確的。

+0

嗨@Draco請從這個問題開始賞金...我仍然遭受這種情況? – Vishal16 2014-06-11 09:30:02

回答

33

正如文檔所述,你不應該自己調用這些方法。

這是如何工作的是,如果UIKit的代碼實際需要在屏幕上呈現該控制器的視圖層次結構,它將調用您的loadView方法。

具體而言,如果任何代碼嘗試在您的視圖控制器上讀取您的view屬性,並且該屬性爲零,則UIViewController的代碼將調用loadView方法。如果您自己沒有實現loadView,那麼默認實現將回退到試圖從nib加載視圖層次結構。

這一切都會在您嘗試呈現視圖控制器並且視圖爲零時自動發生。 (如果您的視圖控制器必須卸載其視圖才能響應內存壓力,這會在您的應用程序運行時發生多次,您獲得的另一種行爲是'免費'且您不想自己致電)

如果這些方法不會在你的視圖控制器中被調用,那麼你如何呈現這個視圖控制器肯定會出現問題,這會阻止UIViewController中的框架代碼調用這些方法。發佈該代碼和某人可以幫助您找出該錯誤。

在嘗試解決錯誤,但是,你應該從你的代碼刪除這些:

[self loadView] 
[self viewDidLoad] 

然後在自己實現viewDidLoad,你將要調用父類與實現[super viewDidLoad]

請記住,在loadView你唯一的責任是將self.view設置爲一些有效的視圖。而已。 UIKit代碼將會看到併爲您撥打viewDidLoad

希望有所幫助。

+0

我仍在琢磨你的答案。這肯定會影響我對視圖控制器的每個主要視圖的所有初始化和啓動方法。如果我能理解這一點,它將幫助我查看內存管理。我不明白的是如何獲得self.view屬性的第一個引用。例如,如果它要進入導航控制器堆棧,我的代碼將引用視圖控制器而不是視圖屬性。我可能需要經驗,但我的經驗告訴我,這不會做到。 – Draco 2012-01-17 17:36:34

+0

讓我們以導航控制器爲例:您將一個新的vc推入堆棧,並且UIKit將嘗試在該vc的視圖中進行動畫處理。你的觀點在這一點上是零,所以框架(他們的代碼,不是你的)會調用loadView。 – 2012-01-17 18:05:05

+0

好的,謝謝。我今晚會嘗試一下。 – Draco 2012-01-17 20:45:04

7

通過Firoze Lafeer的答案是正確的,我只是想說明如何力載荷視圖屬性正確的方法

(void)self.view; 

你不應該這樣做!如果您必須,您做錯了事,但不要在任何情況下自行撥打-loadView-viewDidLoad

+4

感謝您的downvoting。有人顯然喜歡調用視圖加載方法。 – Tricertops 2013-10-01 21:39:17

+0

看來,我在一個點上低估了這一點,我真的不知道爲什麼。我無法撤消它。 – 2015-11-08 13:52:34