一抢蚀、 ARC環(huán)境
單個viewController的生命周期
initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)
loadView:加載view
viewDidLoad:view加載完畢
viewWillAppear:控制器的view將要顯示
viewWillLayoutSubviews:控制器的view將要布局子控件
viewDidLayoutSubviews:控制器的view布局子控件完成
這期間系統(tǒng)可能會多次調(diào)用viewWillLayoutSubviews 、 viewDidLayoutSubviews 倆個方法
viewDidAppear:控制器的view完全顯示
viewWillDisappear:控制器的view即將消失的時候
這期間系統(tǒng)也會調(diào)用viewWillLayoutSubviews 镰禾、viewDidLayoutSubviews 兩個方法
viewDidDisappear:控制器的view完全消失的時候
多個viewControllers跳轉(zhuǎn)
當我們點擊push的時候首先會加載下一個界面然后才會調(diào)用界面的消失方法
initWithCoder:(NSCoder *)aDecoder:ViewController2(如果用xib創(chuàng)建的情況下)
loadView:ViewController2
viewDidLoad:ViewController2
viewWillDisappear:ViewController1將要消失
viewWillAppear:ViewController2將要出現(xiàn)
viewWillLayoutSubviewsViewController2
viewDidLayoutSubviewsViewController2
viewWillLayoutSubviews:ViewController1
viewDidLayoutSubviews:ViewController1
viewDidDisappear:ViewController1完全消失
viewDidAppear:ViewController2完全出現(xiàn)
小結(jié):
-整個控制器聲明周期:? viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews ->? viewDidAppear -> viewWillDisappear -> viewDidDisappear
loadView()
若控制器有關(guān)聯(lián)的 Nib 文件皿曲,該方法會從 Nib 文件中加載 view;如果沒有吴侦,則創(chuàng)建空白 UIView 對象屋休。
自定義實現(xiàn)不應該再調(diào)用父類的該方法。
viewDidLoad()
view 被加載到內(nèi)存后調(diào)用viewDidLoad()备韧。
重寫該方法需要首先調(diào)用父類該方法劫樟。
該方法中可以額外初始化控件,例如添加子控件织堂,添加約束叠艳。
該方法被調(diào)用意味著控制器有可能(并非一定)在未來會顯示。
在控制器生命周期中易阳,該方法只會被調(diào)用一次附较。
viewWillAppear(_:)
該方法在控制器 view 即將添加到視圖層次時以及展示 view 時所有動畫配置前被調(diào)用。
重寫該方法需要首先調(diào)用父類該方法潦俺。
該方法中可以進行操作即將顯示的 view拒课,例如改變狀態(tài)欄的取向,類型事示。
該方法被調(diào)用意味著控制器將一定會顯示早像。
在控制器生命周期中,該方法可能會被多次調(diào)用肖爵。
注意:
如果控制器 A 被展示在另一個控制器 B 的 popover 中卢鹦,那么控制器 B 不會調(diào)用該方法,直到控制器 A 清除劝堪。
viewWillLayoutSubviews()
該方法在通知控制器將要布局 view 的子控件時調(diào)用冀自。
每當視圖的 bounds 改變揉稚,view 將調(diào)整其子控件位置。
該方法可重寫以在 view 布局子控件前做出改變凡纳。
該方法的默認實現(xiàn)為空窃植。
該方法調(diào)用時,AutoLayout 未起作用荐糜。
在控制器生命周期中巷怜,該方法可能會被多次調(diào)用。
viewDidLayoutSubviews()
該方法在通知控制器已經(jīng)布局 view 的子控件時調(diào)用暴氏。
該方法可重寫以在 view 布局子控件后做出改變延塑。
該方法的默認實現(xiàn)為空。
該方法調(diào)用時答渔,AutoLayout 已經(jīng)完成关带。
在控制器生命周期中,該方法可能會被多次調(diào)用沼撕。
viewDidAppear(_:)
該方法在控制器 view 已經(jīng)添加到視圖層次時被調(diào)用宋雏。
重寫該方法需要首先調(diào)用父類該方法。
該方法可重寫以進行有關(guān)正在展示的視圖操作务豺。
在控制器生命周期中磨总,該方法可能會被多次調(diào)用。
viewWillDisappear(_:)
該方法在控制器 view 將要從視圖層次移除時被調(diào)用笼沥。
類似?viewWillAppear(_:)蚪燕。
該方法可重寫以提交變更,取消視圖第一響應者狀態(tài)奔浅。
viewDidDisappear(_:)
該方法在控制器 view 已經(jīng)從視圖層次移除時被調(diào)用馆纳。
類似?viewDidAppear(_:)。
該方法可重寫以清除或隱藏控件汹桦。
didReceiveMemoryWarning()
當內(nèi)存預警時鲁驶,該方法被調(diào)用。
不能直接手動調(diào)用該方法营勤。
該方法可重寫以釋放資源灵嫌、內(nèi)存。
deinit
控制器銷毀時(離開堆)葛作,調(diào)用該方法。
當屏幕旋轉(zhuǎn)猖凛,view 的 bounds 改變赂蠢,其內(nèi)部的子控件也需要按照約束調(diào)整為新的位置,因此也調(diào)用了?viewWillLayoutSubviews()?和?viewDidLayoutSubviews()辨泳。
當在一個控制器內(nèi) Present 新的控制器虱岂,原先的控制器并不會銷毀玖院,但會消失,因此調(diào)用了viewWillDisappear和viewDidDisappear方法第岖。
如果新的控制器 Dismiss难菌,即清除自己,原先的控制器會再一次出現(xiàn)蔑滓,因此調(diào)用了其中的viewWillAppear和viewDidAppear方法郊酒。
若?loadView()?沒有加載 view,viewDidLoad()?會一直調(diào)用?loadView()?加載 view键袱,因此構(gòu)成了死循環(huán)燎窘,程序即卡死。
一蹄咖、創(chuàng)建
1.alloc? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創(chuàng)建對象褐健,分配空間
2.init (initWithNibName) 初始化對象,初始化數(shù)據(jù)
3.loadView? ? ? ? ? ? ? ? ? ? ? ? ? 從nib載入視圖 澜汤,通常這一步不需要去干涉蚜迅。除非你沒有使用xib文件創(chuàng)建視圖
4.viewDidLoad? ? ? ? ? ? ? ? ? 載入完成,可以進行自定義數(shù)據(jù)以及動態(tài)創(chuàng)建其他控件
5.viewWillAppear? ? ? ? ? ? ? 視圖將出現(xiàn)在屏幕之前俊抵,馬上這個視圖就會被展現(xiàn)在屏幕上了
6.viewDidAppear? ? ? ? ? ? ? 視圖已在屏幕上渲染完成
loadView方法
作用:loadView方法是用來負責創(chuàng)建UIViewController的view谁不。首先判斷下有沒有指定storyboard或者xib,如果指定,就會加載它們描述的控制器的view,如果沒有指定,創(chuàng)建一個空的view。
什么時候調(diào)用:每次訪問UIViewController的view务蝠,當view為nil拍谐,就會調(diào)用loadView方法。
ViewController *vc = [[ViewController alloc]init];
底層也會調(diào)用-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil方法馏段。
(1).判斷下有沒有指定nibName,如果指定了,就會去加載指定的xib
(2).如果沒有指定,就會判斷下有沒有跟控制器類名同名的xib,有,就會去加載
(3).判斷下有沒有跟控制器類名同名的xib,但是后綴不帶Controller的xib,如果有,就會去加載
(4).如果沒有任何xib描述控制器的view,就不會加載xib轩拨。會創(chuàng)建一個顏色為clearColor的view。
控制器的view是延遲加載的:創(chuàng)建控制器并不一定會創(chuàng)建控制器的view院喜,等用到時再加載
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];
// 創(chuàng)建控制器,并一定會創(chuàng)建控制器的viewViewController *vc = [[ViewController alloc] init]; vc.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = vc;
?[self.window makeKeyAndVisible];
returnYES;
}```
import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 自定義控制器的view
(void)loadView
{
NSLog(@"%s",func);
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
view.backgroundColor = [UIColor greenColor];
self.view = view;
}
// 控制器的view加載完成的時候調(diào)用
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blueColor];
NSLog(@"%s",func);
}```
此時打印我們發(fā)現(xiàn)控制器的view顏色是紅色的亡蓉,這是因為view的get方法底層中實現(xiàn)了loadView 和 viewDidLoad方法,loadView中將view設(shè)置為綠色喷舀,viewDidLoad方法中又將view設(shè)置成藍色砍濒,但是最后被vc.view.backgroundColor = [UIColor redColor];設(shè)置為紅色传睹。
- loadView
此時沧侥,控制器的 view 還未初始化,可以通過重寫這個方法自定義控制器的 View矗蕊,如果這樣做拿愧,那就不能調(diào)用[super loadView]
- viewDidLoad
在控制器的生命周期中杠河,它只會被調(diào)用一次,此時,view 已經(jīng)初始化好券敌,非常適合做一些頁面的初始化任務唾戚。由于此時 view 的 bounds 尚未確定,所以不適合寫 frame 類型的布局代碼待诅,但是給視圖添加約束沒有影響叹坦。
- viewWillAppear
它會在控制器的視圖將要出現(xiàn)在屏幕中時被調(diào)用,在控制器生命周期中可能會被調(diào)用多次卑雁。在此處募书,適合做一些與視圖出現(xiàn)相關(guān)聯(lián)的任務,例如改變狀態(tài)欄的方向序厉、風格锐膜。
- viewWillLayoutSubviews
當 view 的子視圖即將布局時,此方法會被調(diào)用弛房,觸發(fā)的條件是:
view 被添加到視圖層次中
view 的 bounds 發(fā)生了改變
調(diào)用了- setNeedsLayout方法
調(diào)用了- layoutIfNeeded方法
這個方法是寫 frame 布局代碼的好地方道盏,將 view 的子視圖布局好,每次 view 大小發(fā)生改變時文捶,其子視圖布局也會相應改變荷逞。
- viewDidLayoutSubviews
當 view 的子視圖已經(jīng)布局時,此方法會被調(diào)用粹排,觸發(fā)條件同上种远。
- viewDidAppear
它會在控制器的視圖出現(xiàn)在屏幕后被調(diào)用,此時顽耳,view 的 bounds 已經(jīng)確定坠敷,不過在這里寫布局相關(guān)代碼,可能會反映到屏幕上射富。
- viewWillDisappear
視圖即將從屏幕中消失時觸發(fā)膝迎。
- viewDidDisppear
視圖從屏幕中消失后觸發(fā)。
/ 類的初始化方法
+ (void)initialize;
// 對象初始化方法
- (instancetype)init;
// 從歸檔初始化
- (instancetype)initWithCoder:(NSCoder *)coder;
// Xib初始化后
-(void)awakeFromNib;