2012-05-24 30 views
2

如果一個新的iOS項目在Xcode 4.3.2與空應用程序模板創建,並在AppDelegate.m在iOS上,如果視圖控制器沒有視圖,爲什麼NSLog(@「self.view是%p」,self.view)崩潰?

self.window.rootViewController = [[FooViewController alloc] init]; 

FooViewControllerviewDidLoad,以下內容:

NSLog(@"self.view is %p", self.view); 
NSLog(@"self.view is %@", self.view); 

將打印出來的視圖,所以它看起來像默認loadView將實例化一個視圖,並將其分配給self.view

所以,如果我重寫loadView與所有空方法,並註釋掉上面的第二個NSLog聲明,我預計第一NSLog聲明打印出來0x0,而是應用程序就在這個NSLog線壞內存訪問崩潰的原因。爲什麼會這樣?

回答

2

view property in UIViewController狀態的文檔:

由於訪問此屬性可導致視圖被自動加載,則可以使用isViewLoaded方法,以確定該視圖目前在存儲器中。

它還具有一個鏈接到The View Controller Life Cycle,其中指出:

負載循環過程中發生的步驟如下:

  1. 負載週期被觸發時所述視圖控制器的view屬性被訪問,並且該視圖當前不在內存中。

  2. 視圖控制器調用其方法loadView。該loadView方法的默認實現做兩件事情之一:

    • 如果視圖控制器與故事板相關聯,它加載從故事板視圖。

    • 如果視圖控制器未與故事板關聯,則會創建一個空的UIView對象並將其分配給view屬性。

  3. 視圖控制器調用它的viewDidLoad方法,讓你的子類進行任何額外的負載時間的任務。

所以,當你說:

所以,如果我重寫loadView與所有空方法

你故意打破生命週期,因爲當你的重寫版本loadView完成,它應該已經加載了一個視圖。因爲它沒有,你會崩潰。

5

好吧,經過一個下意識和明顯錯誤的答案,我試了這個。空應用程序模板不會有rootViewController,所以我使用了單個屏幕模板。運行後,我看到你正在發生堆棧溢出。在嘗試訪問self.view時,您正在調用超類的視圖屬性,然後嘗試加載該視圖以返回它,該視圖正在調用viewDidLoad等,據我所知。其他NSLog語句也是這樣。

+0

+1好的研究! –

+0

是的,就是這樣。我錯過了溢出......我刪除了我的答案。 –

+0

感謝您的洞察力。當'self.view'被訪問時......我認爲這只是返回'view'實例變量?由於'view'由'@property(nonatomic,retain)UIView * view定義;'這不就是一個實例變量嗎?如果是這樣的話,那麼'@ synthesize'產生的訪問器應該返回實例變量......你提到了試圖「加載視圖」的超類...它如何加載視圖(從哪裏來?)當視圖爲零? –

相關問題