1 基本說明
話說做了iOS幾年凌盯,對于UIViewController和UIView的生命周期函數(shù)一直不是很重視奶陈,導(dǎo)致了很多模糊的地方抱完。今天專門寫一個(gè)Demo來驗(yàn)證一下,發(fā)現(xiàn)不同加載方式差別還是蠻大的蟆盹。具體Demo地址UIViewController和UIView生命周期加載和卸載孩灯。
2 加載UIViewController
每一種加載方式所調(diào)用的加載方法不同,而且還有一些細(xì)節(jié)地方不同逾滥。蘋果為我們提供了四種默認(rèn)的加載方式,不過我是純代碼黨峰档,AutoLayout以后败匹,我們通過Masonry這個(gè)第三方布局利器來布局,在我Git上也有專門總結(jié)的不同布局解決方案讥巡。接下來我們看看系統(tǒng)的四種方式掀亩,猶豫沒有什么理論性的東西,我就直接上代碼為主了:
- 通過XIB加載欢顷。
- 通過StoryBoard加載槽棍。
- 通過NSCoding協(xié)議加載。
- 通過代碼加載抬驴。
2.1 用XIB加載UIViewController
首先看初始化代碼:
- (IBAction)loadControllerFromXIB:(id)sender {
XIBViewController *xibVC = [[XIBViewController alloc]initWithNibName:@"XIBViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:xibVC animated:YES];
}
當(dāng)我們不實(shí)現(xiàn)loadView
的時(shí)候打印結(jié)果:
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
我發(fā)現(xiàn)一個(gè)很奇怪的現(xiàn)象炼七。如果用XIB加載的控制器,并且實(shí)現(xiàn)了一個(gè)空loadView
,那么我們在XIB設(shè)置的視圖都失效了布持,應(yīng)該是系統(tǒng)返回了一個(gè)默認(rèn)的視圖覆蓋了豌拙。但是用Storyboard加載的視圖,實(shí)現(xiàn)一個(gè)空的loadView
則不會丟失Storyboard里面的視圖题暖,這個(gè)是用XIB和Storyboard的一個(gè)注意點(diǎn)
按傅。
-(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];
}
運(yùn)行結(jié)果:
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,使用一個(gè)空的loadView
沒有影響胧卤。
2.3 用NSCodeing加載UIViewController
初始化代碼:
//這里我就不實(shí)現(xiàn)NSCoding協(xié)議了唯绍,直接傳入一個(gè)nil參數(shù)。
- (IBAction)loadControllerFromCoder:(id)sender {
CoderViewController *coderVC = [[CoderViewController alloc]initWithCoder:nil];
[self.navigationController pushViewController:coderVC animated:YES];
}
運(yùn)行結(jié)果:
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];
}
運(yùn)行結(jié)果:
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];
}
運(yùn)行結(jié)果:
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
//這里是點(diǎn)擊移除以后
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];
}
運(yùn)行結(jié)果:
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
//點(diǎn)擊移除以后
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] 點(diǎn)擊移除
2017-04-15 12:39:02.753 UIViewController和UIView生命周期加載和卸載[60323:1208772] dealloc
4 總結(jié)
UIViewController不同加載方式鉤子函數(shù)總結(jié):
- XIB加載方式
- initWithNibName
- loadView(
注意:如果實(shí)現(xiàn)一個(gè)空的方法灌侣,則XIB設(shè)置的屬性無效,會覆蓋XIB中的設(shè)置
) - viewDidLoad
- Storyboard加載方式
- initWithCoder
- awakeFromNib
- loadView(
實(shí)現(xiàn)是一個(gè)空方法或者不實(shí)現(xiàn)沒有影響
) - viewDidLoad
- NSCoding加載方式
- initWithCoder
- loadView
- viewDidLoad
- 代碼加載方式
- initWithNibName
- init(
這個(gè)是我初始化的時(shí)候主動調(diào)用,如果用initWithNibName傳入nil參數(shù)則不會調(diào)用
) - loadView
- viewDidLoad
我們可以發(fā)現(xiàn)裂问,代碼加載方式和XIB加載方式一模一樣侧啼,如果有XIB則加載XIB,如果沒有XIB則可以代碼添加視圖堪簿。
UIView不同加載方式鉤子函數(shù)總結(jié):
- XIB加載方式
- initWithCoder
- awakeFromNib
- willMoveToWindow
- 代碼加載方式
- initWithFrame(
設(shè)置frame痊乾。
) - init(
init方法調(diào)用
) - willMoveToWindow
- initWithFrame(
我們發(fā)現(xiàn),如果通過init初始化椭更,然后手動設(shè)置Frame哪审。則會導(dǎo)致上面的調(diào)用順序。