ViewController及View的生命周期

1. 起因

我們經(jīng)常能夠在第三方庫的源碼中看到很多loadViewwillMoveToParentViewController:蜡秽、viewDidLayoutSubviews 等等諸如此類的并不是十分常見的方法车荔。這讓永遠都只在viewDidLoad寫作的童鞋們情何以堪吶锻弓。

這些其實都和生命周期有關,和viewController以及view的各種加載順序有關蔫骂。這篇文章就小小擼一下這中間的關系和順序么翰。

2. Controller的生命周期

  • 系統(tǒng)提供了控制器從顯示到消失的四個方法。
  • 千萬不要看到方法名中間出現(xiàn)了view就以為這是視圖的方法纠吴。這些都是控制器的生命周期硬鞍。
    四個方法如下:
//將要顯示,一定要調用super
- (void)viewWillAppear:(BOOL)animated; // Called when the view is about to made visible. Default does nothing

//視圖已經(jīng)顯示
- (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

//視圖已經(jīng)消失
- (void)viewDidDisappear:(BOOL)animated; // Called after the view was dismissed, covered or otherwise hidden. Default does nothing

那四個階段都有什么區(qū)別呢戴已?啥時候用什么呢固该?

2.1 viewWillAppear

當view即將被顯示時調用,此時superview 為nil,也就是說這個是controller還不知道superview是誰糖儡。
這個階段會加載一些高開銷的操作伐坏,例如:鍵盤彈出、特殊的過程動畫(比方說修改狀態(tài)欄握联、導航條顏色等等)這些桦沉。

2.2 viewDidAppear

這個方法表面上看上和viewDidLoad沒有什么區(qū)別啊每瞒。
但是請注意一下細節(jié)。官方是這么描述viewDidLoad纯露。

Called after the view has been loaded剿骨,F(xiàn)or view controllers unarchived from a nib, this is after the view is set.
什么意思?意思是說viewDidLoad在視圖被加載后調用埠褪。如果使用了布局文件浓利,那么會在布局文件加載后被調用。

我們再來看看viewDidAppear的描述:

Called when the view has been fully transitioned onto the screen
意思是視圖出現(xiàn)在屏幕上之后才調用钞速。

為了能夠進一步搞清楚之間的區(qū)別贷掖,我們在不同屏幕上運營一下這兩個方法看看調度的時間點。我們將Xcode默認使用5S去設置一下渴语,屏幕大小是320*568苹威,但是如果運行在6s上會怎么樣。下面做一個小測試驾凶,打印在不同方法執(zhí)行的過程中牙甫,界面的長寬屬性如何,結果如下:

//viewDidLoad    w:320.000000 h:568.000000
//viewWillAppear w:320.000000 h:568.000000
//viewDidAppear  w:414.000000 h:672.000000

有沒有發(fā)現(xiàn)在viewWillAppear狭郑、viewDidAppear獲取的長寬不一致腹暖??所以系統(tǒng)在這兩者之間肯定存在一個屏幕適配的過程翰萨。

  • 從上面的結果可以看到,如果需要調整空間的frame糕殉,其實是放在viewDidAppear中最靠譜的亩鬼。
  • 在自定義cell的時候也有這種問題,如果在init中添加控件的話阿蝶,那么self.frame.size.width也不一定是準確的寬度雳锋,一般解決方法是使用[UIScreen mainScreen].bounds.size.width而不是self.frame.size.width。

2.3 viewWillDisappear

Called when the view is dismissed, covered or otherwise hidden. Default does nothing
視圖被駁回時調用羡洁,覆蓋或以其他方式隱藏玷过。默認情況下不執(zhí)行任何操作。

貌似看上去這個方法沒啥用處筑煮,但是隨著iPhone手機屏幕越來越大辛蚊,左上角的返回按鈕早已夠不到(很多妹子的手都沒有那么大哦!)真仲,所以小手的吃瓜群眾通常喜歡通過側滑的形式返回上一個界面袋马。
而這種側滑返回會出現(xiàn)什么問題呢?當觸發(fā)側滑返回時會調用系統(tǒng)自帶的viewWillDisappear:方法秸应。

  • iOS7新增加了導航控制器側滑手勢虑凛,當觸發(fā)側滑返回時碑宴,會調用系統(tǒng)的viewWillDisappear:方法,取消側滑返回時又會調用viewWillAppear:方法桑谍。

2.4 viewDidDisappear

Called after the view was dismissed, covered or otherwise hidden. Default does nothing
對象的視圖已經(jīng)消失延柠、被覆蓋或是隱藏時調用.

UIViewController類提供一些方法,用來判斷為什么view外觀發(fā)生更改锣披。

- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);

- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);

在四個方法中:
isMovingFromParentViewController 會在viewWillDisappear & viewDidDisappear 方法內部調用這個方法判斷視圖控制器的視圖的隱藏是否因為視圖控制器從它的容器視圖控制器移除贞间。

isBeingDismissed 會在viewWillDisappear & viewDidDisappear 方法內部調用這個方法判斷視圖控制器的視圖的隱藏是否因為視圖控制器被清退 (dismissed,與上面被其它視圖控制器顯示對應盈罐,如信息錄入完成榜跌,返回之前的視圖控制器)。

2.5 控制器View的生命周期

  • loadView:加載view
    • 作用:用來創(chuàng)建控制器的View盅粪。在執(zhí)行的時候會首先判斷有沒有指定的storyboard或者Xib钓葫,如果指定,就會加載它們描述的控制器的View票顾,如果沒有指定础浮,創(chuàng)建一個空的View。
    • 調用時刻:每次訪問Controller的View奠骄,當View為nil豆同,就會調用loadView方法。
  • ViewDidLoad:view加載完畢

    • 當控制器的loadView方法執(zhí)行完畢含鳞,view被創(chuàng)建成功后影锈,就會執(zhí)行viewDidLoad方法。
  • ViewWillAppear:view將要顯示

  • ViewWillLayoutSubViews:view將要布局子控件

  • ViewDidLayoutSubViews:view布局子控件完成

  • ViewDidAppear:view完全顯示

  • ViewWillDisAppear:view即將消失

  • ViewDidDisAppear:view完全消失

3. View的生命周期

我們知道view的創(chuàng)建有init(或new或者跟類名一樣的)的方法蝉绷,銷毀時會自動執(zhí)行dealloc方法鸭廷,但是UIView的生命周期到底是怎樣的呢?系統(tǒng)也同樣提供了四個方法用來管理四個不同時期的內容熔吗,有一點需要注意的是這四個方法都會執(zhí)行辆床,只是添加或者移除的父視圖不同

//將要添加到父視圖上桅狠,要執(zhí)行addSubview
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;

//已經(jīng)添加到父視圖上
- (void)didMoveToSuperview;

//將要添加到窗口
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;

//已經(jīng)添加到窗口
- (void)didMoveToWindow;
  • 某個視圖的層次一改變讼载,該視圖就會收到一次回調。
    • 調用addSubivew:成功后會給該視圖發(fā)送didAddSubivew:回調中跌,觸發(fā)UIView的子類在新增視圖時執(zhí)行其他操作咨堤。
    • didMoveToSuperview:會通知相關視圖他們的上級視圖已經(jīng)變化。添加和移除都會調用,所以要判斷 superView在不在晒他。
    • 視圖移動前會發(fā)出willMoveToSuperview:回調
    • didMoveToWindow:回調和didMoveToSuperview:相似吱型,從命名上能看出其區(qū)別。
    • willMoveToWindow:在視圖移動前發(fā)出的回調陨仅。
    • willRemoveToSubview:回調通知父視圖子視圖即將被刪除

4. 內存警告

  • 首先要判斷一下津滞,當前view有沒有被顯示铝侵。如果正在顯示,做處理触徐,會讓用戶感覺很不舒服咪鲜。
  • 更嚴謹一點,還需要判斷view是否已經(jīng)加載撞鹉。如果沒有加載疟丙,就不需要干掉了。
  • 實際開發(fā)中為了寫的少點鸟雏,都會寫在基類控制器中享郊。
  • 官方說,iOS 6.0以后系統(tǒng)就不會自動清理孝鹊,需要手動清理炊琉。
- (void)didReceiveMemoryWarning { 
   [super didReceiveMemoryWarning]; 
// 第一個判斷條件:當這個view是否正在顯示
// 第二個判斷條件:這個view是否已經(jīng)被加載 
   if (self.isViewLoaded && self.view.window == nil) { 
           [self setView:nil];
   }
Paste_Image.png

·

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市又活,隨后出現(xiàn)的幾起案子苔咪,更是在濱河造成了極大的恐慌,老刑警劉巖柳骄,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件团赏,死亡現(xiàn)場離奇詭異,居然都是意外死亡耐薯,警方通過查閱死者的電腦和手機舔清,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曲初,“玉大人鸠踪,你說我怎么就攤上這事「闯猓” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵械媒,是天一觀的道長目锭。 經(jīng)常有香客問我,道長纷捞,這世上最難降的妖魔是什么痢虹? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮主儡,結果婚禮上奖唯,老公的妹妹穿的比我還像新娘。我一直安慰自己糜值,他們只是感情好丰捷,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布坯墨。 她就那樣靜靜地躺著,像睡著了一般病往。 火紅的嫁衣襯著肌膚如雪捣染。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天停巷,我揣著相機與錄音耍攘,去河邊找鬼。 笑死畔勤,一個胖子當著我的面吹牛蕾各,可吹牛的內容都是我干的。 我是一名探鬼主播庆揪,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼式曲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嚷硫?” 一聲冷哼從身側響起检访,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仔掸,沒想到半個月后脆贵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡起暮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年卖氨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片负懦。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡筒捺,死狀恐怖,靈堂內的尸體忽然破棺而出纸厉,到底是詐尸還是另有隱情系吭,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布颗品,位于F島的核電站肯尺,受9級特大地震影響,放射性物質發(fā)生泄漏躯枢。R本人自食惡果不足惜则吟,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锄蹂。 院中可真熱鬧氓仲,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至舔哪,卻和暖如春欢顷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捉蚤。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工抬驴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缆巧。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓布持,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陕悬。 傳聞我的和親對象是個殘疾皇子题暖,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容