UIView的生命周期總結(jié)

序言:

loadView、viewDidLoad膊升、viewDidAppear示血、initWithNibName、awakeFromNib等經(jīng)常出現(xiàn)在UIViewController中的方法介紹桃笙。

這些方法分別用來(lái)作哪些工作,換言之沙绝,創(chuàng)建自定義的View時(shí)代碼放到以上哪個(gè)方法中搏明。

一個(gè)UIView的生命周期是怎樣的。以上幾個(gè)方法的調(diào)用順序如何闪檬。

通過(guò)IB和代碼加載視圖星著,有什么區(qū)別

UIViewController

視圖層次和根視圖

每個(gè)視圖控制器都維護(hù)一個(gè)視圖層次(view hierarchy)。

因?yàn)槊總€(gè)視圖都有自己的子視圖粗悯,這個(gè)視圖層次其實(shí)也可以理解為一棵樹(shù)狀的數(shù)據(jù)結(jié)構(gòu)虚循。而樹(shù)的根節(jié)點(diǎn),也就是根視圖(root view)样傍,在UIViewController中以view屬性邮丰。它可以被看做是其他所有子視圖的容器。

視圖的加載方式

UIViewController采用懶加載的方式铭乾,也就是說(shuō)第一次訪(fǎng)問(wèn)到view屬性時(shí)才會(huì)加載或創(chuàng)建它。由于視圖由視圖控制器管理娃循,所以討論視圖的加載方式時(shí)炕檩,主要討論視圖控制器的加載方式。

通過(guò)Storyboard加載:這是蘋(píng)果推薦的方式捌斧,也是未來(lái)的趨勢(shì)笛质。

通過(guò)這種方式創(chuàng)建UIViewController對(duì)象的話(huà),首先生成UIStoryboard類(lèi)型的對(duì)象捞蚂,然后調(diào)用這個(gè)對(duì)象的instantiateViewControllerWithIdentifier:方法

通過(guò)Nib文件加載:

Nib文件其實(shí)就是xib文件妇押,Storyboard相當(dāng)于是聚合了多個(gè)nib文件,并且添加了對(duì)不同的UIViewController之間的segue和relationship的管理姓迅。但總的實(shí)現(xiàn)原理非常類(lèi)似

通過(guò)這種方式加載視圖,需要調(diào)用UIViewController類(lèi)的initWithNibName:bundle:方法

通過(guò)loadview方法加載:

這就是通過(guò)代碼加載敲霍。這需要我們?cè)趌oadView 方法中俊马,通過(guò)編程創(chuàng)建自己的視圖層次,并且把把根視圖賦值給UIViewController的view屬性肩杈。

因此柴我,通過(guò)代碼自定義View的時(shí)候,loadView 方法大概是這樣的:

- (void)loadView{

self.view = [[XXXView alloc] init];

}

處理視圖相關(guān)通知

當(dāng)視圖的可見(jiàn)性發(fā)生變化時(shí)扩然,視圖控制器會(huì)自動(dòng)調(diào)用一系列方法來(lái)響應(yīng)變化艘儒。

所有可能的狀態(tài)、方法和狀態(tài)之間的轉(zhuǎn)換關(guān)系在下圖中被明確標(biāo)出夫偶。

可以看到每一個(gè)will方法都有自己對(duì)應(yīng)的did方法界睁。但是如果我們?cè)趙ill方法中開(kāi)始一個(gè)任務(wù),不僅要在對(duì)應(yīng)的did方法中結(jié)束它兵拢,還要考慮到和這個(gè)will方法相反的那個(gè)will方法(注意到Appearing和Disappearing這兩個(gè)狀態(tài)是可以互相轉(zhuǎn)化的)

在運(yùn)行時(shí)展示View

UIKit極大的簡(jiǎn)化了加載和展示View的過(guò)程翻斟,它大概會(huì)按照以下順序執(zhí)行一些任務(wù):

通過(guò)storyboard文件中的信息實(shí)例化視圖

連接outlet和action

把根視圖賦值給UIViewController的view屬性(其實(shí)就是調(diào)用loadView 方法)

調(diào)用UIViewController的awakeFromNib方法。要注意卵佛,在調(diào)用方法前杨赤,的trait collecion為空且子視圖的位置可能不正確

調(diào)用UIViewController的viewDidLoad方法。

此時(shí)已經(jīng)完成了視圖的加載工作截汪,在展示到屏幕之前疾牲,還有以下幾個(gè)步驟:

調(diào)用UIViewController的viewWillAppear方法。

更新視圖的布局

把視圖展示到屏幕上

調(diào)用UIViewController的viewDidAppear方法衙解。

awakeFromNib方法

至此阳柔,第一個(gè)問(wèn)題已經(jīng)幾乎解釋完了,還剩一個(gè)awakeFromNib方法蚓峦。

我們已經(jīng)知道舌剂,awakeFromNib方法被調(diào)用時(shí),所有視圖的outlet和action已經(jīng)連接暑椰,但還沒(méi)有被確定霍转。這個(gè)方法可以算作是和視圖控制器的實(shí)例化配合在一起使用的,因?yàn)橛行┬枰鶕?jù)用戶(hù)喜好來(lái)進(jìn)行設(shè)置的內(nèi)容一汽,無(wú)法存在storyboard中避消,所以可以在awakeFromNib方法中被加載進(jìn)來(lái)。

awakeFromNib方法在視圖控制器的生命周期內(nèi)只會(huì)被調(diào)用一次召夹。因?yàn)樗鸵晥D控制器從nib文件中的解檔密切相關(guān)岩喷,和view的關(guān)系卻不大。

具體方法的解釋

loadView方法

當(dāng)執(zhí)行到loadView方法時(shí)监憎,視圖控制器已經(jīng)從nib文件中被解檔并創(chuàng)建好了纱意,接下來(lái)的任務(wù)主要是對(duì)view進(jìn)行初始化。

loadView方法在UIViewController對(duì)象的view屬性被訪(fǎng)問(wèn)到且為空的時(shí)候調(diào)用鲸阔。

這是它與awakeFromNib方法的一個(gè)區(qū)別偷霉。假設(shè)我們?cè)谔幚韮?nèi)存警告時(shí)釋放view屬性(其實(shí)并不應(yīng)該這么做迄委,這里舉個(gè)例子):self.view = nil。因此loadView方法在視圖控制器的生命周期內(nèi)可能會(huì)被多次調(diào)用腾它。

這個(gè)方法不應(yīng)該被直接調(diào)用跑筝,而是由系統(tǒng)自動(dòng)調(diào)用。它會(huì)加載或創(chuàng)建一個(gè)view并把它賦值給UIViewController的view屬性瞒滴。

在創(chuàng)建view的過(guò)程中曲梗,首先會(huì)根據(jù)nibName去找對(duì)應(yīng)的Nib文件然后加載。如果nibName為空妓忍,或找不到對(duì)應(yīng)的Nib文件虏两,則會(huì)創(chuàng)建一個(gè)空視圖(這種情況一般是純代碼,也就是為什么說(shuō)代碼構(gòu)建View的時(shí)候世剖,要重寫(xiě)loadView 方法)定罢。

注意在重寫(xiě)loadView方法的時(shí)候,不要調(diào)用父類(lèi)的方法旁瘫。

viewDidLoad方法

loadView方法執(zhí)行完之后祖凫,就會(huì)執(zhí)行viewDidLoad方法。此時(shí)整個(gè)視圖層次(view hierarchy)已經(jīng)被放到內(nèi)存中酬凳。

無(wú)論是從nib文件加載惠况,還是通過(guò)純代碼編寫(xiě)界面,viewDidLoad方法都會(huì)執(zhí)行宁仔。我們可以重寫(xiě)這個(gè)方法稠屠,對(duì)通過(guò)nib文件加載的view做一些其他的初始化工作。比如可以移除一些視圖翎苫,修改約束权埠,加載數(shù)據(jù)等。

viewWillAppear和viewDidAppear方法

在視圖加載完成煎谍,并即將顯示在屏幕上時(shí)攘蔽,會(huì)調(diào)用viewWillAppear方法,在這個(gè)方法里呐粘,可以改變當(dāng)前屏幕方向或狀態(tài)欄的風(fēng)格等秩彤。

當(dāng)viewWillAppear方法執(zhí)行完后,系統(tǒng)會(huì)執(zhí)行viewDidAppear方法事哭。在這個(gè)方法中,還可以對(duì)視圖做一些關(guān)于展示效果方面的修改瓜富。

視圖的生命歷程

到目前為止鳍咱,我們已經(jīng)了解了每個(gè)方法的作用,接下來(lái)就把整個(gè)流程梳理一遍与柑。

[objc] view plain copy

-[ViewController initWithCoder:]或-[ViewController initWithNibName:Bundle]:首先從歸檔文件中加載UIViewController對(duì)象谤辜。即使是純代碼蓄坏,也會(huì)把nil作為參數(shù)傳給后者。

-[UIView awakeFromNib]:作為第一個(gè)方法的助手丑念,方便處理一些額外的設(shè)置涡戳。

-[ViewController loadView]:創(chuàng)建或加載一個(gè)view并把它賦值給UIViewController的view屬性

-[ViewController viewDidLoad]:此時(shí)整個(gè)視圖層次(view hierarchy)已經(jīng)被放到內(nèi)存中,可以移除一些視圖脯倚,修改約束渔彰,加載數(shù)據(jù)等

-[ViewController viewWillAppear:]:視圖加載完成,并即將顯示在屏幕上,還沒(méi)有設(shè)置動(dòng)畫(huà)推正,可以改變當(dāng)前屏幕方向或狀態(tài)欄的風(fēng)格等恍涂。

-[ViewController viewWillLayoutSubviews]:即將開(kāi)始子視圖位置布局

-[ViewController viewDidLayoutSubviews]:用于通知視圖的位置布局已經(jīng)完成

-[ViewController viewDidAppear:]:視圖已經(jīng)展示在屏幕上,可以對(duì)視圖做一些關(guān)于展示效果方面的修改植榕。

-[ViewController viewWillDisappear:]:視圖即將消失

-[ViewController viewDidDisappear:]:視圖已經(jīng)消失

如果考慮UIViewController可能在某個(gè)時(shí)刻釋放整個(gè)view再沧。那么再次加載視圖時(shí)顯然會(huì)從步驟3開(kāi)始。因?yàn)榇藭r(shí)的UIViewController對(duì)象依然存在尊残。

總結(jié)

1炒瘸,只有init系列的方法,如initWithNibName需要自己調(diào)用,其他方法如loadView和awakeFromNib則是系統(tǒng)自動(dòng)調(diào)用寝衫。而viewWill/Did系列的方法則類(lèi)似于回調(diào)和通知顷扩,也會(huì)被自動(dòng)調(diào)用。

2竞端,純代碼寫(xiě)視圖布局時(shí)需要注意屎即,要手動(dòng)調(diào)用loadView方法,而且不要調(diào)用父類(lèi)的loadView方法事富。純代碼和用IB的區(qū)別僅存在于loadView方法及其之前技俐,編程時(shí)需要注意的也就是loadView方法。

3统台,除了initWithNibName和awakeFromNib方法是處理視圖控制器外雕擂,其他方法都是處理視圖。這兩個(gè)方法在視圖控制器的生命周期里只會(huì)調(diào)用一次贱勃。

Life cycle

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末井赌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贵扰,更是在濱河造成了極大的恐慌仇穗,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件戚绕,死亡現(xiàn)場(chǎng)離奇詭異纹坐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)舞丛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)耘子,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)果漾,“玉大人,你說(shuō)我怎么就攤上這事谷誓∪拚希” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵捍歪,是天一觀(guān)的道長(zhǎng)户辱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)费封,這世上最難降的妖魔是什么焕妙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮弓摘,結(jié)果婚禮上焚鹊,老公的妹妹穿的比我還像新娘。我一直安慰自己韧献,他們只是感情好末患,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著锤窑,像睡著了一般璧针。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渊啰,一...
    開(kāi)封第一講書(shū)人閱讀 52,549評(píng)論 1 312
  • 那天探橱,我揣著相機(jī)與錄音,去河邊找鬼绘证。 笑死隧膏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嚷那。 我是一名探鬼主播胞枕,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼魏宽!你這毒婦竟也來(lái)了腐泻?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤队询,失蹤者是張志新(化名)和其女友劉穎派桩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蚌斩,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铆惑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸭津。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肠缨,靈堂內(nèi)的尸體忽然破棺而出逆趋,到底是詐尸還是另有隱情,我是刑警寧澤晒奕,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布闻书,位于F島的核電站,受9級(jí)特大地震影響脑慧,放射性物質(zhì)發(fā)生泄漏魄眉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一闷袒、第九天 我趴在偏房一處隱蔽的房頂上張望坑律。 院中可真熱鬧,春花似錦囊骤、人聲如沸晃择。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宫屠。三九已至,卻和暖如春滑蚯,著一層夾襖步出監(jiān)牢的瞬間浪蹂,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工告材, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坤次,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓创葡,卻偏偏與公主長(zhǎng)得像浙踢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灿渴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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