UIViewController和UIView不一樣加載方式的生命週期函數

1 基本說明

話說作了iOS幾年,對於UIViewController和UIView的生命週期函數一直不是很重視,致使了不少模糊的地方。今天專門寫一個Demo來驗證一下,發現不一樣加載方式差異仍是蠻大的。git

2 加載UIViewController

每一種加載方式所調用的加載方法不一樣,並且還有一些細節地方不一樣。蘋果爲咱們提供了四種默認的加載方式,不過我是純代碼黨,AutoLayout之後,咱們經過Masonry這個第三方佈局利器來佈局,在我Git上也有專門總結的不一樣佈局解決方案。接下來咱們看看系統的四種方式,猶豫沒有什麼理論性的東西,我就直接上代碼爲主了:github

  • 經過XIB加載。app

  • 經過StoryBoard加載。函數

  • 經過NSCoding協議加載。佈局

  • 經過代碼加載。code

2.1 用XIB加載UIViewController

首先看初始化代碼:生命週期

- (IBAction)loadControllerFromXIB:(id)sender {
    XIBViewController *xibVC = [[XIBViewController alloc]initWithNibName:@"XIBViewController" bundle:[NSBundle mainBundle]];
    [self.navigationController pushViewController:xibVC animated:YES];
}

當咱們不實現loadView的時候打印結果:get

2017-04-15 12:05:32.974 UIViewController和UIView生命週期加載和卸載[59883:1192231] initWithNibName
2017-04-15 12:05:32.987 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewDidLoad
2017-04-15 12:05:32.987 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewWillAppear
2017-04-15 12:05:32.996 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewWillLayoutSubviews
2017-04-15 12:05:32.997 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewDidLayoutSubviews
2017-04-15 12:05:33.002 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewWillLayoutSubviews
2017-04-15 12:05:33.002 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewDidLayoutSubviews
2017-04-15 12:05:33.506 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewDidAppear
2017-04-15 12:05:37.142 UIViewController和UIView生命週期加載和卸載[59883:1192231] clickButton
//pop之後
2017-04-15 12:05:42.334 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewWillDisappear
2017-04-15 12:05:42.837 UIViewController和UIView生命週期加載和卸載[59883:1192231] viewDidDisappear
2017-04-15 12:05:42.838 UIViewController和UIView生命週期加載和卸載[59883:1192231] dealloc

我發現一個很奇怪的現象。若是用XIB加載的控制器,而且實現了一個空loadView,那麼咱們在XIB設置的視圖都失效了,應該是系統返回了一個默認的視圖覆蓋了。可是用Storyboard加載的視圖,實現一個空的loadView則不會丟失Storyboard裏面的視圖,這個是用XIB和Storyboard的一個注意點源碼

-(void)loadView{
    [super loadView];
    NSLog(@"loadView");
}

2.2 用Storyboard加載UIViewController

初始化代碼:博客

- (IBAction)laodControllerFromSB:(id)sender {
    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Second" bundle:[NSBundle mainBundle]];
    SBViewController *sbVC = [sb instantiateViewControllerWithIdentifier:@"SBViewController"];
    [self.navigationController pushViewController:sbVC animated:YES];
}

運行結果:

2017-04-15 12:26:45.364 UIViewController和UIView生命週期加載和卸載[59932:1194239] initWithCoder
2017-04-15 12:26:45.365 UIViewController和UIView生命週期加載和卸載[59932:1194239] awakeFromNib
2017-04-15 12:26:45.368 UIViewController和UIView生命週期加載和卸載[59932:1194239] loadView
2017-04-15 12:26:45.368 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLoad
2017-04-15 12:26:45.368 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillAppear
2017-04-15 12:26:45.372 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillLayoutSubviews
2017-04-15 12:26:45.373 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLayoutSubviews
2017-04-15 12:26:45.877 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidAppear
//pop之後
2017-04-15 12:26:50.669 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillDisappear
2017-04-15 12:26:51.172 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidDisappear
2017-04-15 12:26:51.172 UIViewController和UIView生命週期加載和卸載[59932:1194239] dealloc

對於Storyboard,使用一個空的loadView沒有影響。

2.3 用NSCodeing加載UIViewController

初始化代碼:

//這裏我就不實現NSCoding協議了,直接傳入一個nil參數。
- (IBAction)loadControllerFromCoder:(id)sender {
    CoderViewController *coderVC = [[CoderViewController alloc]initWithCoder:nil];
    [self.navigationController pushViewController:coderVC animated:YES];
}

運行結果:

2017-04-15 12:30:25.962 UIViewController和UIView生命週期加載和卸載[59932:1194239] initWithCoder
2017-04-15 12:30:25.963 UIViewController和UIView生命週期加載和卸載[59932:1194239] loadView
2017-04-15 12:30:25.963 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLoad
2017-04-15 12:30:25.963 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillAppear
2017-04-15 12:30:25.967 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillLayoutSubviews
2017-04-15 12:30:25.967 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLayoutSubviews
2017-04-15 12:30:25.968 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillLayoutSubviews
2017-04-15 12:30:25.968 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLayoutSubviews
2017-04-15 12:30:26.470 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidAppear
//pop之後
2017-04-15 12:30:28.034 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillDisappear
2017-04-15 12:30:28.537 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidDisappear
2017-04-15 12:30:28.537 UIViewController和UIView生命週期加載和卸載[59932:1194239] dealloc

2.4 用代碼加載UIViewController

初始化代碼:

- (IBAction)loadControllerWithNone:(id)sender {
    CodeViewController *codeVC = [[CodeViewController alloc]init];
    [self.navigationController pushViewController:codeVC animated:YES];
}

運行結果:

2017-04-15 12:31:48.785 UIViewController和UIView生命週期加載和卸載[59932:1194239] initWithNibName
2017-04-15 12:31:48.786 UIViewController和UIView生命週期加載和卸載[59932:1194239] init
2017-04-15 12:31:48.787 UIViewController和UIView生命週期加載和卸載[59932:1194239] loadView
2017-04-15 12:31:48.787 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLoad
2017-04-15 12:31:48.788 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillAppear
2017-04-15 12:31:48.792 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillLayoutSubviews
2017-04-15 12:31:48.792 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLayoutSubviews
2017-04-15 12:31:48.792 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillLayoutSubviews
2017-04-15 12:31:48.792 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidLayoutSubviews
2017-04-15 12:31:49.293 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidAppear
//pop之後
2017-04-15 12:31:55.594 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewWillDisappear
2017-04-15 12:31:56.098 UIViewController和UIView生命週期加載和卸載[59932:1194239] viewDidDisappear
2017-04-15 12:31:56.098 UIViewController和UIView生命週期加載和卸載[59932:1194239] dealloc

3 加載UIView

3.1 用XIB加載UIView

初始化代碼:

- (IBAction)loadViewFromXib:(id)sender {
    XibView *xibView = [[[NSBundle mainBundle]loadNibNamed:@"XIBView" owner:self options:nil] lastObject];
    [self.view addSubview:xibView];
}

運行結果:

2017-04-15 12:33:22.194 UIViewController和UIView生命週期加載和卸載[59932:1194239] initWithCoder
2017-04-15 12:33:22.195 UIViewController和UIView生命週期加載和卸載[59932:1194239] awakeFromNib
2017-04-15 12:33:22.195 UIViewController和UIView生命週期加載和卸載[59932:1194239] willMoveToWindow
2017-04-15 12:33:22.195 UIViewController和UIView生命週期加載和卸載[59932:1194239] willMoveToSuperview
2017-04-15 12:33:22.196 UIViewController和UIView生命週期加載和卸載[59932:1194239] didMoveToWindow
2017-04-15 12:33:22.196 UIViewController和UIView生命週期加載和卸載[59932:1194239] didMoveToSuperview
2017-04-15 12:33:22.197 UIViewController和UIView生命週期加載和卸載[59932:1194239] layoutSubviews
//這裏是點擊移除之後
2017-04-15 12:33:25.769 UIViewController和UIView生命週期加載和卸載[59932:1194239] willMoveToSuperview
2017-04-15 12:33:25.770 UIViewController和UIView生命週期加載和卸載[59932:1194239] willMoveToWindow
2017-04-15 12:33:25.771 UIViewController和UIView生命週期加載和卸載[59932:1194239] didMoveToWindow
2017-04-15 12:33:25.771 UIViewController和UIView生命週期加載和卸載[59932:1194239] didMoveToSuperview
2017-04-15 12:33:25.771 UIViewController和UIView生命週期加載和卸載[59932:1194239] dealloc

3.2 用代碼加載UIView

初始化代碼:

- (IBAction)loadViewWithNone:(id)sender {
    CodeView *codeView = [[CodeView alloc]init];
    codeView.backgroundColor = [UIColor greenColor];
    codeView.frame = CGRectMake(0, 500, 100, 50);
    [self.view addSubview:codeView];
}

運行結果:

2017-04-15 12:38:57.562 UIViewController和UIView生命週期加載和卸載[60323:1208772] initWithFrame
2017-04-15 12:38:57.562 UIViewController和UIView生命週期加載和卸載[60323:1208772] init
2017-04-15 12:38:57.562 UIViewController和UIView生命週期加載和卸載[60323:1208772] willMoveToWindow
2017-04-15 12:38:57.563 UIViewController和UIView生命週期加載和卸載[60323:1208772] willMoveToSuperview
2017-04-15 12:38:57.563 UIViewController和UIView生命週期加載和卸載[60323:1208772] didMoveToWindow
2017-04-15 12:38:57.563 UIViewController和UIView生命週期加載和卸載[60323:1208772] didMoveToSuperview
2017-04-15 12:38:57.564 UIViewController和UIView生命週期加載和卸載[60323:1208772] layoutSubviews
//點擊移除之後
2017-04-15 12:39:02.751 UIViewController和UIView生命週期加載和卸載[60323:1208772] willMoveToSuperview
2017-04-15 12:39:02.752 UIViewController和UIView生命週期加載和卸載[60323:1208772] willMoveToWindow
2017-04-15 12:39:02.752 UIViewController和UIView生命週期加載和卸載[60323:1208772] didMoveToWindow
2017-04-15 12:39:02.752 UIViewController和UIView生命週期加載和卸載[60323:1208772] didMoveToSuperview
2017-04-15 12:39:02.752 UIViewController和UIView生命週期加載和卸載[60323:1208772] 點擊移除
2017-04-15 12:39:02.753 UIViewController和UIView生命週期加載和卸載[60323:1208772] dealloc

4 總結

UIViewController不一樣加載方式鉤子函數總結:

  • XIB加載方式

    • initWithNibName

    • loadView(注意:若是實現一個空的方法,則XIB設置的屬性無效,會覆蓋XIB中的設置)

    • viewDidLoad

  • Storyboard加載方式

    • initWithCoder

    • awakeFromNib

    • loadView(實現是一個空方法或者不實現沒有影響)

    • viewDidLoad

  • NSCoding加載方式

    • initWithCoder

    • loadView

    • viewDidLoad

  • 代碼加載方式

    • initWithNibName

    • init(這個是我初始化的時候主動調用,若是用initWithNibName傳入nil參數則不會調用)

    • loadView

    • viewDidLoad

咱們能夠發現,代碼加載方式和XIB加載方式如出一轍,若是有XIB則加載XIB,若是沒有XIB則能夠代碼添加視圖。

UIView不一樣加載方式鉤子函數總結:

  • XIB加載方式

    • initWithCoder

    • awakeFromNib

    • willMoveToWindow

  • 代碼加載方式

    • initWithFrame(設置frame。)

    • init(init方法調用)

    • willMoveToWindow

咱們發現,若是經過init初始化,而後手動設置Frame。則會致使上面的調用順序。

源碼連接UIViewController和UIView生命週期加載和卸載。博客地址博客地址

相關文章
相關標籤/搜索