View的聲明周期詳解

  • iOS控制器平時總調用viewDidload其流程也是從 viewDidLoad->viewWillAppear -> viewDidAppear ->viewWillDisappear -> viewDidDisappear基本的流程就這樣了,那還有沒有呢???答案是當然有具體是什么呢?下面具體來研究下,小知識也能翻船??
  • 先看看API吧??
- (void)loadView; // This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.
- (void)loadViewIfNeeded NS_AVAILABLE_IOS(9_0); // Loads the view controller's view if it has not already been set.
- (void)viewWillUnload NS_DEPRECATED_IOS(5_0,6_0) __TVOS_PROHIBITED;
- (void)viewDidUnload NS_DEPRECATED_IOS(3_0,6_0) __TVOS_PROHIBITED; // Called after the view controller's view is released and set to nil. For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc.

- (void)viewDidLoad; // Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers unarchived from a nib, this is after the view is set.
- (BOOL)isViewLoaded NS_AVAILABLE_IOS(3_0);
- (void)viewWillAppear:(BOOL)animated;    // Called when the view is about to made visible. Default does nothing
- (void)viewDidAppear:(BOOL)animated;     // Called when the view has been fully transitioned onto the screen. Default does nothing
- (void)viewWillDisappear:(BOOL)animated; // Called when the view is dismissed, covered or otherwise hidden. Default does nothing
- (void)viewDidDisappear:(BOOL)animated;  // Called after the view was dismissed, covered or otherwise hidden. Default does nothing

// Called just before the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. The default is a nop.
- (void)viewWillLayoutSubviews NS_AVAILABLE_IOS(5_0);
// Called just after the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. The default is a nop.
- (void)viewDidLayoutSubviews NS_AVAILABLE_IOS(5_0);
- (void)didReceiveMemoryWarning; // Called when the parent application receives a memory warning. On iOS 6.0 it will no longer clear the view by default.

看到這里很慚愧,里面很多方法平時很少用,那么具體的流程到底是怎樣的呢?
自己寫執行代碼打印輸入如下:
從A到B

viewDidLoad-----A
viewWillAppear-----A
viewWillLayoutSubviews-----A
viewDidLayoutSubviews-----A
viewDidAppear-----A
viewDidLoad-----B
viewWillDisappear-----A
viewWillAppear-----B
viewWillLayoutSubviews-----B
viewDidLayoutSubviews-----B
viewDidDisappear-----A
viewDidAppear-----B

  • AB的過程中,B加載后(即viewDidLoad->B)此時A將會消失,等到B視圖出現之前A徹底視圖消失
    從B到A

viewWillDisappear-----B
viewWillAppear-----A
viewDidDisappear-----B
viewDidAppear-----A

  • BA的過程中,首先B視圖將會消失,等到A視圖徹底出現之前,B視圖才會徹底消失.
  • 再從AB

viewDidLoad-----B
viewWillDisappear-----A
viewWillAppear-----B
viewWillLayoutSubviews-----B
viewDidLayoutSubviews-----B
viewDidDisappear-----A
viewDidAppear-----B

  1. loadView:每次訪問view時,就會調用self.view的get方法,在get方法中判斷self.view==nil.不為nil就直接返回view,等于nil就去調用loadView方法。loadView方法會去判斷有無指定storyboard/Xib文件,如果有就去加載storyboard/Xib描述的控制器View,如果沒有則系統默認創建一個空的view,賦給self.view。loadView方法有可能被調用多次(每當訪問self.view并且為nil時就會調用一次);
  2. viewDidLoad:view加載完成時調用(在loadView方法執行后調用)也有可能執行多次(self.view==nil且被訪問時)
  3. awakeFromNib:通過storyboard創建控制器加載了控制器以及控制器view的nib文件,此方法在initWithCoder調用后被調用。而通過Xib創建控制器只加載了控制器view的nib文件,所以控制器的awakeFromNib方法不會被調用
    awakeFromNib方法是在將統一歸檔中的所有對象都讀取并初始化完成后才會被調用。
    4.viewWillAppearview即將可見時調用
    5.viewWillLayoutSubViews:view即將布局子視圖時調用
    6.viewDidLayoutSubviews:view完成子視圖布局后調用
    7.viewDidAppear:view已經顯示后調用
    8.viewWillDisappear:view即將消失、被覆蓋或者隱藏事調用此方法
    9.viewDidDisappear:view已經消失、被覆蓋或者隱藏時調用此方法
    10.didReceiveMemoryWarning:當收到內存警告時調用此方法
    11.viewWillUnload:當內存過低時,需要釋放一些不需要使用的視圖時,即將釋放時調用(iOS6以后被廢棄)
    12.viewDidUnload:當內存過低,釋放了一些不需要的視圖時調用(iOS6以后被廢棄)
    總結如下圖所示
    view的聲明周期圖
內存警告時view的處理機制
  • iOS6以前(不包含iOS6)當內存警告時,我們會在viewDidUnload中手動回收viewController的子視圖或者ViewControllerview([self.view removeFromSuperVIew];self.view = nil;),當view再次被訪問到時,就會調用loadView方法,viewControllerview及其子視圖會被重新創建。
  • 內存警告時,viewDidUnload一定會被調用
  • loadView會被調用多次
    iOS6以后蘋果廢棄了viewWillUnloadviewDidUnload方法,所以以前在viewDidUnload中處理內存警告的代碼就需要移動到didReceiveMemoryWarning中。但如果你覺得這樣就沒有問題了,那就錯了。iOS6以后蘋果廢棄了那兩個方法的同時也添加了內部處理view的方式,具體的處理機制如下:

iOS6及以后,內存警告時系統會回收ViewController的View的CALayer里的BitMap(CABackingStore類型,它的內容是直接用于渲染到屏幕,它是View消耗內存的大戶)。view和calayer占的內存極少, 數量級也就在byte和kbyte之間,所以系統只回收了BitMap,但是這里所謂的回收只是給BitMap占用的內存打了一個volatile標記表明這部分內存是可能隨時被其它數據占用,平時沒內存警告時正在使用的內存標記為In use,完全被釋放回收的標記為Not in use。概括起來也就是說:iOS6及以后的內存警告時,系統會給用于渲染視圖的數據(BitMap)內存打一個volatile, ViewController的View的架子結構并不會回收,當View再次被訪問時,雖然View的架子結構會用重建,但觸發drawRect來渲染界面時,如果view對應的BitMap數據內存沒有被占用則會被View的drawRect方法直接渲染出來且內存被標記為in use,從而這塊內存又可以獨享了;如果已被其它數據占用,那么BitMap必須要重建。所以可以看到整個重建過程不再是由loadView來做的,它是通過對view的訪問來觸發的。但是,請注意, 如果說在iOS6及以后ViewController的loadView方法只會被調用一次,這種說法是不完全準確的。因為:如果在didReceiveMemoryWarning里把ViewController的View也回收了([self.view removeFromSuperview];self.view = nil;),那么當再次有對View訪問時,loadView會被調用以進行完全最徹底的重建(想想也是,ViewController的View都沒了,不調loadView來重建那怎么辦呢)。

iOS6這種的設計的優點:

  • 視圖結構和視圖數據的分離;
  • 內存警告后系統只回收的是內存大戶視圖數據,但是回收不是完全的清掉,而只是做個標記,這樣既做到減小了每次重建BitMap 的成本,同時也把這部分內存開放出去可以隨時被別的數據占用;
  • 重建時,充其量是重建BitMap(沒被占用時是直接用不用重建)
寫作不易,如有錯誤歡迎大家指正,如果喜歡請給個小????
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容