iOS UIViewController生命周期

前言
一直忽略的視圖控制器的生命周期問題,當(dāng)被面試官追問時(shí),發(fā)現(xiàn)自己知之甚淺,特此,總結(jié)下來(lái)。

視圖控制器創(chuàng)建方式

方式一(init加載):
CodeViewController *VC = [[CodeViewController alloc]init];

方式二(xib加載):
XibViewController *VC = [[XibViewController alloc]initWithNibName:@"XibViewController" bundle:[NSBundle mainBundle]];
 
方式三(Storyboard加載):
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"StoryBoardVC" bundle:[NSBundle mainBundle]];
StbViewController *VC = [sb instantiateViewControllerWithIdentifier:@"StoryBoardViewController"];

方式四(NSCoding協(xié)議加載):
NSCoderViewController  *VC = [[NSCoderViewController alloc]initWithCoder:nil];

[self presentViewController:VC animated:YES completion:nil];

方式一輸出:

2019-01-18 17:27:08.801819+0800 LifeCyleVC[6591:1028822] +[CodeViewController initialize]
2019-01-18 17:27:08.802087+0800 LifeCyleVC[6591:1028822] -[CodeViewController initWithNibName:bundle:]
2019-01-18 17:27:08.802268+0800 LifeCyleVC[6591:1028822] -[CodeViewController init]
2019-01-18 17:27:08.802917+0800 LifeCyleVC[6591:1028822] -[CodeViewController loadView]
2019-01-18 17:27:08.803134+0800 LifeCyleVC[6591:1028822] -[CodeViewController viewDidLoad]
2019-01-18 17:27:08.804736+0800 LifeCyleVC[6591:1028822] -[CodeViewController viewWillAppear:]
2019-01-18 17:27:08.806116+0800 LifeCyleVC[6591:1028822] -[CodeViewController viewWillLayoutSubviews]
2019-01-18 17:27:08.806240+0800 LifeCyleVC[6591:1028822] -[CodeViewController viewDidLayoutSubviews]
2019-01-18 17:27:09.307427+0800 LifeCyleVC[6591:1028822] -[CodeViewController viewDidAppear:]

方式二輸出:

2019-01-18 16:32:07.414444+0800 LifeCyleVC[5502:834637] +[XibViewController initialize]
2019-01-18 16:32:07.414708+0800 LifeCyleVC[5502:834637] -[XibViewController initWithNibName:bundle:]
2019-01-18 16:32:07.416775+0800 LifeCyleVC[5502:834637] -[XibViewController loadView]
2019-01-18 16:32:07.416925+0800 LifeCyleVC[5502:834637] -[XibViewController viewDidLoad]
2019-01-18 16:32:07.418489+0800 LifeCyleVC[5502:834637] -[XibViewController viewWillAppear:]
2019-01-18 16:32:07.420077+0800 LifeCyleVC[5502:834637] -[XibViewController viewWillLayoutSubviews]
2019-01-18 16:32:07.420202+0800 LifeCyleVC[5502:834637] -[XibViewController viewDidLayoutSubviews]
2019-01-18 16:32:07.922041+0800 LifeCyleVC[5502:834637] -[XibViewController viewDidAppear:]

方式三輸出:

2019-01-21 18:35:39.242503+0800 LifeCyleVC[50009:3700866] +[NextViewController initialize]
2019-01-21 18:35:39.246208+0800 LifeCyleVC[50009:3700866] -[NextViewController initWithCoder:]
2019-01-21 18:35:39.246431+0800 LifeCyleVC[50009:3700866] -[NextViewController awakeFromNib]
2019-01-21 18:35:39.256965+0800 LifeCyleVC[50009:3700866] -[NextViewController loadView]
2019-01-21 18:35:39.257161+0800 LifeCyleVC[50009:3700866] -[NextViewController viewDidLoad]
2019-01-21 18:35:39.259448+0800 LifeCyleVC[50009:3700866] -[NextViewController viewWillAppear:]
2019-01-21 18:35:39.266274+0800 LifeCyleVC[50009:3700866] -[NextViewController viewWillLayoutSubviews]
2019-01-21 18:35:39.266608+0800 LifeCyleVC[50009:3700866] -[NextViewController viewDidLayoutSubviews]
2019-01-21 18:35:39.778369+0800 LifeCyleVC[50009:3700866] -[NextViewController viewDidAppear:]

方式四輸出:

2019-01-18 17:19:47.437557+0800 LifeCyleVC[6466:1012816] +[NSCoderViewController initialize]
2019-01-18 17:19:47.437860+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController initWithCoder:]
2019-01-18 17:19:47.438482+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController loadView]
2019-01-18 17:19:47.438682+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController viewDidLoad]
2019-01-18 17:19:47.440091+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController viewWillAppear:]
2019-01-18 17:19:47.441523+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController viewWillLayoutSubviews]
2019-01-18 17:19:47.441673+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController viewDidLayoutSubviews]
2019-01-18 17:19:47.441743+0800 LifeCyleVC[6466:1012816] -[ViewController viewWillLayoutSubviews]
2019-01-18 17:19:47.441821+0800 LifeCyleVC[6466:1012816] -[ViewController viewDidLayoutSubviews]
2019-01-18 17:19:47.942351+0800 LifeCyleVC[6466:1012816] -[NSCoderViewController viewDidAppear:]

視圖銷毀調(diào)用方法:

2019-01-21 17:33:44.561425+0800 LifeCyleVC[49067:3464394] -[ViewController viewWillDisappear:]
2019-01-21 17:33:44.569643+0800 LifeCyleVC[49067:3464394] -[ViewController viewWillLayoutSubviews]
2019-01-21 17:33:44.569801+0800 LifeCyleVC[49067:3464394] -[ViewController viewDidLayoutSubviews]
2019-01-21 17:33:45.073069+0800 LifeCyleVC[49067:3464394] -[ViewController viewDidDisappear:]
2019-01-21 17:33:45.073069+0800 LifeCyleVC[49067:3464394] -[ViewController dealloc]

+(void)load

https://developer.apple.com/documentation/objectivec/nsobject/1418815-load?language=objc

Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

當(dāng)一個(gè)類或者類別被加載到OC運(yùn)行時(shí)時(shí)調(diào)用,每個(gè)類、類別的+load方法,在程序運(yùn)行時(shí)只會(huì)加載一次

  • 先加載父類的+load方法,再加載子類的+load方法,不同的類的+load方法調(diào)用和編譯時(shí)添加的順序一致(Compile Sources)
  • 先加載類的+load方法(包括子類,也就是說子類的+load方法在類別的+load方法調(diào)用之前調(diào)用),再加載類別的+load方法,不同的類別的+load方法調(diào)用和編譯時(shí)添加的順序一致(Compile Sources)
  • 子類的+load方法未實(shí)現(xiàn)并不會(huì)調(diào)用父類的+load方法

概括來(lái)說:類-->子類-->類別

+(void)initialize

https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=occ

Initializes the class before it receives its first message.

初始化類,在類第一次收到消息之前調(diào)用

  • 先調(diào)用父類的initialize,再調(diào)用子類的initialize方法
  • runtime發(fā)送initialize消息是線程安全的,因?yàn)閕nitialize是在類發(fā)送第一條消息之前調(diào)用,并且任何線程都必須在完成initialize方法之后再向類發(fā)送消息。
  • 若是子類沒有實(shí)現(xiàn)initialize方法,則會(huì)調(diào)用父類initialize方法,所以一個(gè)父類的initialize可能被多次調(diào)用,子類實(shí)現(xiàn)initialize方法時(shí),會(huì)覆蓋父類initialize方法.
  • 當(dāng)有多個(gè)Category都實(shí)現(xiàn)了initialize方法,會(huì)覆蓋類中的方法,只執(zhí)行一個(gè)(會(huì)執(zhí)行Compile Sources 列表中最后一個(gè)Category 的initialize方法)

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-initwithnibname?language=occ

Returns a newly initialized view controller with the nib file in the specified bundle.

從指定的nib文件中初始化視圖控制器。

- (instancetype)init

https://developer.apple.com/documentation/objectivec/nsobject/1418641-init?language=occ

Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated.

由子類實(shí)現(xiàn)初始化一個(gè)新的對(duì)象(接收者)后立即內(nèi)存分配

- (instancetype)initWithCoder:(NSCoder *)aDecoder

當(dāng)從nib或者storyboard中初始化對(duì)象時(shí),則會(huì)調(diào)用該方法??梢杂迷摲椒▉?lái)重新定義我們?cè)趎ib中已經(jīng)設(shè)置的各項(xiàng)屬性。

  • 遵循NSCoding協(xié)議的對(duì)象調(diào)用才能調(diào)用該方法進(jìn)行初始化對(duì)象。

- (void)awakeFromNib

https://developer.apple.com/documentation/objectivec/nsobject/1402907-awakefromnib?language=occ

Prepares the receiver for service after it has been loaded from an Interface Builder archive, or nib file.

當(dāng)從nib文件或者Interface Builder archive中加載視圖調(diào)用

  • 在初始化的過程中,每個(gè)對(duì)象都會(huì)使用它合適的方法進(jìn)行初始化。遵循NSCoding協(xié)議的對(duì)象調(diào)用initWithCoder:進(jìn)行初始化,不遵循NSCoding協(xié)議的其他對(duì)象調(diào)用init方法初始化。
  • 該方法必須在對(duì)象被加載和初始化之后調(diào)用
  • 當(dāng)一個(gè)對(duì)象調(diào)用awakeFromNib方法時(shí),要確保所有的outlet和事件關(guān)聯(lián)都被建立。

- (void)loadView

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview?language=occ

Creates the view that the controller manages.

創(chuàng)建視圖控制器的視圖

如果視圖控制器關(guān)聯(lián)的是nib文件,那么就從nib文件中加載view,如果沒有關(guān)聯(lián)nib文件,則該方法創(chuàng)建一個(gè)UIView對(duì)象。

- (void)viewDidLoad

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload?language=occ

Called after the controller's view is loaded into memory.

當(dāng)一個(gè)控制器的視圖被加載到內(nèi)存中時(shí)調(diào)用

- (void)viewWillAppear:(BOOL)animated

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear?language=objc

Notifies the view controller that its view is about to be added to a view hierarchy.

通知視圖控制器,視圖將要被添加到視圖層次結(jié)構(gòu)中。
你可以覆蓋這個(gè)方法執(zhí)行自定義任務(wù)與視圖顯示相關(guān),例如你可以在此方法中改變狀態(tài)欄的風(fēng)格。

- (void)viewWillLayoutSubviews

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621437-viewwilllayoutsubviews?language=occ

Called to notify the view controller that its view is about to layout its subviews.

通知視圖控制器將要布局它的子視圖時(shí)調(diào)用。

- (void)viewDidLayoutSubviews

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621398-viewdidlayoutsubviews?language=occ

Called to notify the view controller that its view has just laid out its subviews.

通知視圖控制器剛剛布局好子視圖時(shí)調(diào)用。

- (void)viewDidAppear:(BOOL)animated

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621423-viewdidappear?language=objc

Notifies the view controller that its view was added to a view hierarchy.

通知視圖控制器它的視圖已經(jīng)加到視圖層次結(jié)構(gòu)中了。

- (void)viewWillDisappear:(BOOL)animated

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621485-viewwilldisappear?language=objc

Notifies the view controller that its view is about to be removed from a view hierarchy.

通知視圖控制器視圖將要從它的視圖層次結(jié)構(gòu)中移除。

- (void)viewDidDisappear:(BOOL)animated

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621477-viewdiddisappear?language=occ

Notifies the view controller that its view was removed from a view hierarchy.

通知視圖控制器視圖已經(jīng)從它的視圖層次結(jié)構(gòu)中移除。

- (void)dealloc

https://developer.apple.com/documentation/objectivec/nsobject/1571947-dealloc?language=occ

Deallocates the memory occupied by the receiver.

釋放接收器占用的內(nèi)存。

結(jié)語(yǔ)
由于筆者能力有限,若文章中有什么錯(cuò)誤或者需要補(bǔ)充的部分,希望大家不吝賜教,非常感謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容