天天看點

[轉]UIViewController中各方法調用順序及功能詳

原帖位址:http://blog.samoay.me/post/view/11

UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, viewWillAppear, viewDidAppear, viewWillLayoutSubviews,viewDidLayoutSubviews,viewWillDisappear, viewDidDisappear方法,按照調用順序說明如下:

調試日志:

2013-07-14 12:15:49.048 VCTest[13412:907] initWithNibName:bundle  /  initWithCoder #如果使用的StoryBoard
2013-07-14 12:15:49.056 VCTest[13412:907] loadView
2013-07-14 12:15:49.059 VCTest[13412:907] viewDidLoad
2013-07-14 12:15:49.061 VCTest[13412:907] viewWillAppear
2013-07-14 12:15:49.078 VCTest[13412:907] viewWillLayoutSubviews
2013-07-14 12:15:49.083 VCTest[13412:907] viewDidLayoutSubviews
2013-07-14 12:15:49.445 VCTest[13412:907] viewDidAppear
2013-07-14 12:16:00.624 VCTest[13412:907] viewWillDisappear
2013-07-14 12:16:00.997 VCTest[13412:907] viewDidDisappear
           

1. initWithNibName:bundle

初始化UIViewController,執行關鍵資料初始化操作,注意這裡不要做view相關操作,view在loadView方法中才初始化,這時loadView還未調用。如果使用StoryBoard進行視圖管理,程式不會直接初始化一個UIViewController,StoryBoard會自動初始化或在segue被觸發時自動初始化,是以方法initWithNibName:bundle:不會被調用。如果在代碼裡面使用instantiateViewControllerWithIdentifier:方法顯示初始化一個UIViewController,則initWithCoder方法會被調用。

如果是通過調用initWithNibName:bundle指定nib檔案名初始化的話,ViewController會根據此nib來建立View。如果name參數為nil,則ViewController會通過以下兩個步驟找到與其關聯的nib:

1)如果ViewController的類名以“Controller”結尾,例如ViewController的類名是MyViewController,則查找是否存在MyView.nib;

2)找跟ViewController類名一樣的檔案,例如MyViewController,則查找是否存在MyViewController.nib

2. loadView

當通路UIViewController的view屬性時,view如果此時是nil,那麼VC會自動調用loadView方法來初始化一個UIView并指派給view屬性。此方法用在初始化關鍵view,需要注意的是,在view初始化之前,不能先調用view的getter方法,否則将導緻死循環(除非先調用了

[supper loadView];

)。

-(void)loadView{
    NSLog(@"loadView");
    //錯誤,将導緻死循環,是以此時view=nil,VC會再次調用loadView來初始化view
    self.view.backgroundColor = [UIColor greenColor];
}

-(void)loadView{
    NSLog(@"loadView");
    //正确,先初始化view
    self.view = [[MyView alloc] init];
    self.view.backgroundColor = [UIColor greenColor];
}
           

如果沒有重載loadView方法,則UIViewController會從nib或StoryBoard中查找預設的loadView,預設的loadView會傳回一個空白的UIView對象。

3. viewDidLoad

當VC的view對象載入記憶體後調用,用于對view進行額外的初始化操作

4. viewWillAppear

在view即将添加到視圖層級中(顯示給使用者)且任意顯示動畫切換之前調用(這個時候supperView還是nil)。這個方法中完成任何與視圖顯示相關的任務,例如改變視圖方向、狀态欄方向、視圖顯示樣式等

5. viewDidAppear

在view被添加到視圖層級中,顯示動畫切換之後調用(這時view已經添加到supperView中)。在這個方法中執行視圖顯示相關附件任務,如果重載了這個方法,必須在方法中調用

[supper viewDidAppear];

6. viewWillLayoutSubviews

view即将布局其Subviews。比如view的bounds改變了(例如狀态欄從不顯示到顯示,視圖方向變化),要調整Subviews的位置,在調整之前要做的一些工作就可以在該方法中實作。

7. viewDidLayoutSubviews

view已經布局其Subviews。比如view的bounds改變了(例如狀态欄從不顯示到顯示,視圖方向變化),已經調整Subviews的位置,在調整完成之後要做的一些工作就可以在該方法中實作。

8. viewWillDisappear

view即将從superView中移除且移除動畫切換之前,此時還沒有調用removeFromSuperview。

9. viewDidDisappear

view從superView中移除,移除動畫切換之後調用,此時已調用removeFromSuperview。

10. viewWillUnload

在VC的view對象從記憶體中釋放之前調用,可以在view被釋放前做一些資源清理操作。在iOS6.0開始就廢棄了,該方法不再會調用

11. viewDidUnload

在VC的view對象從記憶體中釋放之後調用,可以在view被釋放後做一些view相關的引用清理操作,此時view為nil。在iOS6.0開始就廢棄了,該方法不再會調用

繼續閱讀