iOS最詳盡的控制器生命周期剖析

導(dǎo)讀

推薦筆者朋友寫的一篇關(guān)于控制器生命周期的博文.里面寫的十分詳盡,看過之后,你會(huì)發(fā)現(xiàn)作者是花了心思花了精力來寫的.看過這篇博客,你會(huì)對控制器的生命周期方法會(huì)有一個(gè)更深入更全面的了解.
我在這里分享給大家,希望大家喜歡,你的支持是創(chuàng)作者的最大動(dòng)力:原文鏈接http://www.reibang.com/p/23a83706d773

前言

在面試中,面試官可能會(huì)問這樣的問題亚脆,loadView有什么作用寥假,它與viewDidLoad有何區(qū)別

首先我們得知道沉填,控制器view是通過懶加載的方式進(jìn)行加載的疗隶,即用到的時(shí)候再加載。

loadView方法

當(dāng)我們用到控制器view時(shí)翼闹,就會(huì)調(diào)用控制器view的get方法斑鼻,在get方法內(nèi)部,首先判斷view是否已經(jīng)創(chuàng)建猎荠,如果已存在坚弱,則直接返回存在的view,如果不存在关摇,則調(diào)用控制器的loadView方法史汗,在控制器沒有被銷毀的情況下,loadView也可能會(huì)被執(zhí)行多次

viewDidLoad方法

當(dāng)控制器的loadView方法執(zhí)行完畢拒垃,view被創(chuàng)建成功后,就會(huì)執(zhí)行viewDidLoad方法瓷蛙,該方法與loadView方法一樣悼瓮,也有可能被執(zhí)行多次。在開發(fā)中艰猬,我們可能從未遇到過執(zhí)行多次的情況横堡,那什么時(shí)候會(huì)執(zhí)行多次呢?

比如A控制器push出B控制器冠桃,此時(shí)命贴,窗口顯示的是B控制器的view,此時(shí)如果收到內(nèi)存警告食听,我們一般會(huì)將A控制器中沒用的變量及view銷毀掉胸蛛,之后當(dāng)我們從B控制器pop到A控制器時(shí),就會(huì)再次執(zhí)行A控制器的loadView方法與viewDidLoad方法樱报。

如下圖所示葬项,注意控制臺打印


控制器view的加載

先看一下Demo的文件結(jié)構(gòu),ViewController為A控制器迹蛤,TestViewController為B控制器


1.通過storyboard加載
當(dāng)控制器通過storyboard加載時(shí)民珍,需要指定storyboard的名稱,控制器view最終就是storyboard所描述的樣子盗飒,這個(gè)比較簡單嚷量,不做詳細(xì)闡述
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"TestViewController" bundle:nil];
TestViewController *testVC = [storyboard instantiateInitialViewController];
[self.navigationController pushViewController:testVC animated:YES];
}

2.通過xib加載
當(dāng)控制器view通過xib加載的時(shí)候,可能會(huì)出現(xiàn)三種情況

a. 指定xib名稱(OtherViewController.xib)
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
TestViewController *testVC = [[TestViewController alloc] initWithNibName:@"OtherViewController" bundle:nil];
[self.navigationController pushViewController:testVC animated:YES];
}
當(dāng)我們指定了xib的名稱逆趣,loadView方法就會(huì)去加載對應(yīng)的xib(OtherViewController.xib)蝶溶,最終是這個(gè)樣子的


b.不指定xib名稱1
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
TestViewController *testVC = [[TestViewController alloc] init];
[self.navigationController pushViewController:testVC animated:YES];
}
如果我們不指定xib名稱,loadView就會(huì)加載與控制器同名的xib(TestViewController.xib)汗贫,最終是這個(gè)樣子的


c.不指定xib名稱2
我們先將TestViewController.xib這個(gè)文件刪除掉身坐,這個(gè)時(shí)候秸脱,我們再來運(yùn)行程序,結(jié)果是這樣的


根據(jù)上圖我們可以得知部蛇,當(dāng)沒有指定xib名稱摊唇,且沒有與控制器同名的xib時(shí),會(huì)加載前綴與控制器名相同而不帶controller的xib(TestView.xib)涯鲁。

3.不通過sb\xib加載
將TestView.xib這個(gè)文件也刪除掉巷查,再來運(yùn)行程序,結(jié)果是這樣的


這么黑抹腿,難道沒有創(chuàng)建控制器view岛请?


如上圖,控制器view是存在的警绩,只不過顏色為clearColor崇败,所以看到的黑色其實(shí)是UIWindow的

4.重寫loadView方法
我們重寫TestViewController的loadView方法,里面不做任何事
- (void)loadView {
}

運(yùn)行程序看結(jié)果


結(jié)果跟上面一樣黑肩祥,不同的是后室,這次并沒有創(chuàng)建view,注意看上圖最外層并不是UIView

如果我們希望控制器view加載出來的時(shí)候不是UIView而是其他控件混狠,比如UIImageView岸霹,那我們就可以重寫loadView
- (void)loadView{
self.view = [[UIImageView alloc] init];
}


結(jié)論

1.重寫loadView方法,則會(huì)根據(jù)重寫的loadView方法創(chuàng)建view
2.控制器通過storyboard加載将饺,則根據(jù)storyboard的描述創(chuàng)建view
3.控制器view通過xib加載贡避,則根據(jù)nibName對應(yīng)的xib創(chuàng)建view
4.沒有指定nibName,則根據(jù)與控制器同名的xib創(chuàng)建view
5.沒有同名的xib予弧,則根據(jù)與控制器名前綴相同不帶controller的xib創(chuàng)建view
6.如果都沒有刮吧,則創(chuàng)建一個(gè)空白的xib

小細(xì)節(jié)

在上面的2、3兩點(diǎn)結(jié)論中掖蛤,不知道大家有沒有一個(gè)疑問


為什么上面是說的控制器皇筛,而下面卻說的控制器view?
筆者結(jié)合控制器的awakeFromNib方法給大家說明一下這個(gè)問題
顧名思義坠七,當(dāng)控制器從nib加載的時(shí)候就會(huì)調(diào)用這個(gè)方法

先來看看通過storyboard加載的情況

//A控制器中代碼
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"TestViewController" bundle:nil];
  TestViewController *testVC = [storyboard instantiateInitialViewController];
  [self.navigationController pushViewController:testVC animated:YES];
}
//B控制器中代碼
- (void)awakeFromNib {
  NSLog(@"B通過nib加載");
}

控制臺打印了“B通過nib加載”水醋,即調(diào)用了B控制器的awakeFromNib方法

將之前刪除的TestViewController.xib文件重寫添加進(jìn)去,再來看通過xib加載的情況

//A控制器中代碼改為如下
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  TestViewController *testVC =[[TestViewController alloc] init];
  [self.navigationController pushViewController:testVC animated:YES];
}
//B控制器中代碼不變

控制臺沒有任何輸出彪置,即B控制器的awakeFromNib方法并沒有被調(diào)用

結(jié)論

storyboard加載的是控制器及控制器view拄踪,而xib加載的僅僅只是控制器的view

最后給大家補(bǔ)充幾個(gè)小的知識點(diǎn)

1.控制器view的生命周期:viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews
-> viewDidAppear -> viewWillDisappear -> viewDidDisappear

2.內(nèi)存警告?zhèn)鬟f過程:手機(jī)內(nèi)存不足產(chǎn)生事件->通知應(yīng)用程序->調(diào)用應(yīng)用程序代理方法->把事件傳遞給窗口->窗口傳給控制器->調(diào)用控制器的內(nèi)存警告方法

3.xib描述控制器view時(shí),其File's Owner為對應(yīng)的控制器拳魁,當(dāng)通過xib自定義view或自定義cell時(shí)惶桐,F(xiàn)ile's Owner不能填寫自定義view或者cell的類名

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子姚糊,更是在濱河造成了極大的恐慌贿衍,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件救恨,死亡現(xiàn)場離奇詭異贸辈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肠槽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門擎淤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秸仙,你說我怎么就攤上這事嘴拢。” “怎么了寂纪?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵席吴,是天一觀的道長。 經(jīng)常有香客問我捞蛋,道長抢腐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任襟交,我火速辦了婚禮,結(jié)果婚禮上伤靠,老公的妹妹穿的比我還像新娘捣域。我一直安慰自己,他們只是感情好宴合,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布焕梅。 她就那樣靜靜地躺著,像睡著了一般卦洽。 火紅的嫁衣襯著肌膚如雪贞言。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天阀蒂,我揣著相機(jī)與錄音该窗,去河邊找鬼。 笑死蚤霞,一個(gè)胖子當(dāng)著我的面吹牛酗失,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昧绣,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼规肴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拖刃,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤删壮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后兑牡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體央碟,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年发绢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了硬耍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡边酒,死狀恐怖经柴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情墩朦,我是刑警寧澤坯认,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站氓涣,受9級特大地震影響牛哺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜劳吠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一引润、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧痒玩,春花似錦淳附、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至草讶,卻和暖如春洽糟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堕战。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工坤溃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘱丢。 一個(gè)月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓浇雹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親屿讽。 傳聞我的和親對象是個(gè)殘疾皇子昭灵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容