感謝以下文章作者的共享:
- 01—控制器的生命周期
- UIViewController的生命周期及iOS程序執(zhí)行順序]
- UIViewController 生命周期
- UIViewController生命周期-學(xué)習(xí)筆記]
- iOS最詳盡的控制器生命周期剖析
- UIViewController中各方法調(diào)用順序及功能詳解
viewController的生命周期
viewController生命周期如圖:
- viewController生命周期各個(gè)方法的調(diào)用順序:
-> alloc :創(chuàng)建對象,分配空間
-> init(initWithNibName) : 初始化對象,初始化數(shù)據(jù)
-> loadView : 從nib載入視圖,通常這一步不需要去干涉。除非你沒有使用xib文件創(chuàng)建視圖。(在定制 VC 時(shí),如果覆蓋loadView方法,不需要調(diào)用[super loadView] 方法.)
-> viewDidLoad : view載入完成,可以進(jìn)行自定義數(shù)據(jù),以及動(dòng)態(tài)創(chuàng)建其他控件(通常會(huì)在這里做各種初始數(shù)據(jù)的載入,初始設(shè)定等很多內(nèi)容)
-> viewWillAppear : 視圖即將出現(xiàn)在屏幕上的時(shí)候(進(jìn)行一些顯示前的處理。比如鍵盤彈出,一些特殊的過程動(dòng)畫比如狀態(tài)條和* navigationbar* 顏色,可以在這個(gè)視圖設(shè)定不同方向時(shí)該如何顯示)
-> viewWillLayoutSubviews:view即將布局其Subviews。比如view的bounds改變了(例如狀態(tài)欄從不顯示到顯示,視圖方向變化),要調(diào)整Subviews的位置,在調(diào)整之前要做的一些工作就可以在該方法中實(shí)現(xiàn)。
-> viewDidLayoutSubviews:view已經(jīng)布局其Subviews。比如view的bounds改變了(例如狀態(tài)欄從不顯示到顯示,視圖方向變化),已經(jīng)調(diào)整Subviews的位置,在調(diào)整完成之后要做的一些工作就可以在該方法中實(shí)現(xiàn)。
-> viewDidAppear : 視圖已在屏幕上渲染完成(切換動(dòng)畫后,如果有需要的操作,可以在這里加入相關(guān)代碼)
-> viewWillDisappear : 視圖將被從屏幕移除之前執(zhí)行,此時(shí)還沒有調(diào)用removeFromSuperview。(視圖切換時(shí),當(dāng)前視圖即將被移除、覆蓋、時(shí)會(huì)在這里做一些善后處理和設(shè)置)
-> viewDidDisAppear : 視圖已經(jīng)從屏幕上移除了,用戶看不到這個(gè)視圖了。此時(shí)已調(diào)用removeFromSuperview。
-> viewWillUnload : 發(fā)生內(nèi)存警告時(shí),在對其他視圖銷毀前調(diào)用。
-> viewDidUnload : 發(fā)生內(nèi)存警告時(shí),如果視圖不是當(dāng)前屏幕正在顯示的視圖,viewDidUnload將會(huì)被執(zhí)行,本視圖所有子視圖將被銷毀以釋放內(nèi)存,此時(shí)開發(fā)者需要手動(dòng)對viewLoad、viewDidLoad中創(chuàng)建的對象釋放內(nèi)存。因?yàn)楫?dāng)這個(gè)視圖再次顯示在屏幕上的時(shí)候viewLoad、viewDidLoad會(huì)再次被調(diào)用。
-> dealloc : 視圖被銷毀,此處會(huì)對你在init和viewDidLoad中創(chuàng)建的對象進(jìn)行釋放。
創(chuàng)建view的三種方式:
- 使用代碼創(chuàng)建vc
- 使用代碼創(chuàng)建vc時(shí),我們根據(jù)需要手動(dòng)的創(chuàng)建 VC 中的數(shù)據(jù),若自己定制 VC,還需要在* init* 方法中調(diào)用 [super init] 方法.
- 如果覆蓋loadView方法,則不需要調(diào)用[super loadView] 方法.
- 使用xib創(chuàng)建vc
xib其實(shí)最終是會(huì)把我們的設(shè)置保存成一個(gè)數(shù)據(jù)集,當(dāng)需要初始化構(gòu)建 VC 的時(shí)候,回去讀取記錄的數(shù)據(jù)集,然后幫我們動(dòng)態(tài)創(chuàng)建* VC* . 因此它在初始化的時(shí)候會(huì)先去看是否實(shí)現(xiàn)* initWithCoder* 方法,如果該類實(shí)現(xiàn)了該方法,就直接調(diào)用 initWithCoder 方法創(chuàng)建對象,如果沒有實(shí)現(xiàn)就調(diào)用init方法.調(diào)用完初始化方法緊接著調(diào)用* awakeFromNib* 方法,在這個(gè)方法里邊我們可以做進(jìn)一步的初始化工作.
- 通過storyboard創(chuàng)建
要點(diǎn)總結(jié)
- ViewController 的 view 是使用了 Lazy Init 方式創(chuàng)建
- loadView和viewDidLoad的區(qū)別就在于,loadView時(shí)view還沒有生成;viewDidLoad時(shí),view已經(jīng)生成了。loadView只會(huì)被調(diào)用一次,而viewDidLoad可能會(huì)被調(diào)用多次(View可能會(huì)被加載多次)
- viewDidLayoutSubviews在以下情況會(huì)被調(diào)用
1、init初始化不會(huì)觸發(fā)layoutSubviews
2、addSubview會(huì)觸發(fā)layoutSubviews
3、設(shè)置view的Frame會(huì)觸發(fā)layoutSubviews,當(dāng)然前提是frame的值設(shè)置前后發(fā)生了變化
4、滾動(dòng)一個(gè)UIScrollView會(huì)觸發(fā)layoutSubviews
5、旋轉(zhuǎn)Screen會(huì)觸發(fā)父UIView上的layoutSubviews事件
6、改變一個(gè)UIView大小的時(shí)候也會(huì)觸發(fā)父UIView上的layoutSubviews事件