日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

探究 UIViewController 生命周期

發布時間:2025/5/22 编程问答 87 豆豆
生活随笔 收集整理的這篇文章主要介紹了 探究 UIViewController 生命周期 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

由于種種原因,掘金等第三方平臺博客不再保證能夠同步更新,歡迎移步 GitHub:github.com/kingcos/Per…。謝謝!

Lifecycle of UIViewController in iOS

DateNotesSwiftXcode
2017-03-10首次提交3.08.2.1

前言

對象的生命周期一直是開發者所需要關心的,教授 CS193p 的老師 Paul 也詳細的講述了 UIViewController 的生命周期。為了記述這一過程,故作此文。由于 Xcode 提供了純代碼和 Storyboard(Xib 同理)兩種布局 UI 的方式,因此初始化部分略有不同。

為了方便觀察,我創建了一個 BaseViewController,繼承自原本的 UIViewController,重寫其中的生命周期方法,并讓后續新的控制器繼承自該控制器,以便觀察。

本文對應的 Demo 可以在 github.com/kingcos/UIV… 查看、下載。

Initialization

Storyboard

OUTPUT: init(coder:) awakeFromNib()

init(coder:)

  • 當使用 Storyboard 時,控制器的構造器為 init(coder:)。
  • 該構造器為必需構造器,如果重寫其他構造器,則必須重寫該構造器。
  • 該構造器為可失敗構造器,即有可能構造失敗,返回 nil。
  • 該方法來源自 NSCoding 協議,而 UIViewController 遵從這一協議。
  • 該方法被調用意味著控制器有可能(并非一定)在未來會顯示。
  • 在控制器生命周期中,該方法只會被調用一次。

awakeFromNib()

  • 當使用 Storyboard 時,該方法會被調用。
  • 當調用該方法時,將保證所有的 outlet 和 action 連接已經完成。
  • 該方法內部必須調用父類該方法,雖然默認實現為空,但 UIKit 中許多類的該方法為非空。
  • 由于控制器中對象的初始化順序不能確定,所以構造器中不應該向其他對象發送消息,而應當在 awakeFromNib() 中安全地發送。
  • 通常使用 awakeFromNib() 可以進行在設計時無法完成的必要額外設置。

Code

OUTPUT: init(nibName:bundle:) - NibName: nil, Bundle: nil

init(nibName:bundle:)

  • 當使用純代碼創建控制器,控制器的構造器為 init(nibName:bundle:)。
  • 雖然使用代碼創建時調用了該構造器,但傳入的參數均為 nil。

OUTPUT: loadView() viewDidLoad() viewWillAppear viewWillLayoutSubviews() - Optional((162.0, 308.0, 50.0, 50.0)) viewDidLayoutSubviews() - Optional((67.0, 269.0, 241.0, 129.0)) viewDidAppear viewWillDisappear viewDidDisappear deinit

loadView()

  • loadView() 即加載控制器管理的 view。
  • 不能直接手動調用該方法;當 view 被請求卻為 nil 時,該方法加載并創建 view。
  • 若控制器有關聯的 Nib 文件,該方法會從 Nib 文件中加載 view;如果沒有,則創建空白 UIView 對象。
  • 如果使用 Interface Builder 創建 view,則務必不要重寫該方法。
  • 可以使用該方法手動創建視圖,且需要將根視圖分配為 view;自定義實現不應該再調用父類的該方法。
  • 執行其他初始化操作,建議放在 viewDidLoad() 中。

viewDidLoad()

  • view 被加載到內存后調用 viewDidLoad()。
  • 重寫該方法需要首先調用父類該方法。
  • 該方法中可以額外初始化控件,例如添加子控件,添加約束。
  • 該方法被調用意味著控制器有可能(并非一定)在未來會顯示。
  • 在控制器生命周期中,該方法只會被調用一次。

viewWillAppear(_:)

  • 該方法在控制器 view 即將添加到視圖層次時以及展示 view 時所有動畫配置前被調用。
  • 重寫該方法需要首先調用父類該方法。
  • 該方法中可以進行操作即將顯示的 view,例如改變狀態欄的取向,類型。
  • 該方法被調用意味著控制器將一定會顯示。
  • 在控制器生命周期中,該方法可能會被多次調用。

注意: 如果控制器 A 被展示在另一個控制器 B 的 popover 中,那么控制器 B 不會調用該方法,直到控制器 A 清除。

viewWillLayoutSubviews()

  • 該方法在通知控制器將要布局 view 的子控件時調用。
  • 每當視圖的 bounds 改變,view 將調整其子控件位置。
  • 該方法可重寫以在 view 布局子控件前做出改變。
  • 該方法的默認實現為空。
  • 該方法調用時,AutoLayout 未起作用。
  • 在控制器生命周期中,該方法可能會被多次調用。

viewDidLayoutSubviews()

  • 該方法在通知控制器已經布局 view 的子控件時調用。
  • 該方法可重寫以在 view 布局子控件后做出改變。
  • 該方法的默認實現為空。
  • 該方法調用時,AutoLayout 已經完成。
  • 在控制器生命周期中,該方法可能會被多次調用。

viewDidAppear(_:)

  • 該方法在控制器 view 已經添加到視圖層次時被調用。
  • 重寫該方法需要首先調用父類該方法。
  • 該方法可重寫以進行有關正在展示的視圖操作。
  • 在控制器生命周期中,該方法可能會被多次調用。

viewWillDisappear(_:)

  • 該方法在控制器 view 將要從視圖層次移除時被調用。
  • 類似 viewWillAppear(_:)。
  • 該方法可重寫以提交變更,取消視圖第一響應者狀態。

viewDidDisappear(_:)

  • 該方法在控制器 view 已經從視圖層次移除時被調用。
  • 類似 viewDidAppear(_:)。
  • 該方法可重寫以清除或隱藏控件。

didReceiveMemoryWarning()

  • 當內存預警時,該方法被調用。
  • 不能直接手動調用該方法。
  • 該方法可重寫以釋放資源、內存。

deinit

  • 控制器銷毀時(離開堆),調用該方法。

Note

Rotation

OUTPUT: willTransition(to:with:) viewWillLayoutSubviews() - Optional((67.5, 269.5, 240.0, 128.0)) viewDidLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) viewWillLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) viewDidLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) viewWillLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0)) viewDidLayoutSubviews() - Optional((213.5, 123.5, 240.0, 128.0))

  • 當 view 轉變,會調用 willTransition(to:with:) 方法。
  • 當屏幕旋轉,view 的 bounds 改變,其內部的子控件也需要按照約束調整為新的位置,因此也調用了 viewWillLayoutSubviews() 和 viewDidLayoutSubviews()。

Present & Dismiss

OUTPUT: viewWillDisappear viewDidDisappear viewDidDisappear viewWillAppear viewDidAppear

  • 當在一個控制器內 Present 新的控制器,原先的控制器并不會銷毀,但會消失,因此調用了 viewWillDisappear 和 viewDidDisappear 方法。
  • 如果新的控制器 Dismiss,即清除自己,原先的控制器會再一次出現,因此調用了其中的 viewWillAppear 和 viewDidAppear 方法。

死循環

class LoopViewController: UIViewController {override func loadView() {print(#function)}override func viewDidLoad() {print(#function)let _ = view}} 復制代碼

OUTPUT: loadView() viewDidLoad() loadView() viewDidLoad() loadView() viewDidLoad() loadView() viewDidLoad() loadView()

  • 若 loadView() 沒有加載 view,viewDidLoad() 會一直調用 loadView() 加載 view,因此構成了死循環,程序即卡死。

Reference

  • CS193P_2017
  • UIViewController 相關生命周期總結

也歡迎您關注我的微博 @萌面大道V & 簡書

總結

以上是生活随笔為你收集整理的探究 UIViewController 生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美亚洲国产成人 | 五月综合激情日本mⅴ | 日韩一级片av| 天天干天天操天天操 | 91精品国产综合久久香蕉 | 国产精品久久久久久在线观看 | 国内激情视频 | 美女久久久久久久久久 | 女性裸体下面张开 | 激情另类视频 | 无码人妻精品一区二区三区温州 | 草女人视频 | 亚洲精品一区二区三区婷婷月 | 裸体毛片 | 老司机午夜免费视频 | 天天成人| 性高湖久久久久久久久免费 | 两性囗交做爰视频 | 日韩福利电影在线观看 | 中国三级视频 | 性猛交xxxx乱大交孕妇2十 | 久久国内精品 | 三级av毛片 | sm调教羞耻姿势图片 | 日本伊人影院 | 波多野吉衣在线视频 | 日本黄色激情视频 | 国产精品剧情一区 | 国产高清不卡 | 二级黄色录像 | 日韩不卡一二区 | 女女h百合无遮涩涩漫画软件 | 欧美激情精品久久 | 国产91熟女高潮一区二区 | 色妞av| 999精品免费视频 | 99热99在线| 免费一级网站 | jizz内谢中国亚洲jizz | 在线免费看黄视频 | 日本天堂在线播放 | www.男人的天堂 | 国产黄| 久久美女免费视频 | av一区二区三区四区 | 国产真人做爰毛片视频直播 | 亚洲一区二区精品在线观看 | 先锋影音中文字幕 | 亚洲成熟女性毛茸茸 | 国产精品欧美精品 | 国产高清中文字幕 | 国产91丝袜在线观看 | 黄色性情网站 | 99免费精品| 四虎av | 国产熟女一区二区三区五月婷 | 香蕉成人在线视频 | 九九热精品视频在线观看 | 亚洲精品av中文字幕在线在线 | 国产乱淫av片免费看 | 欧美老肥熟| 8090理论片午夜理伦片 | 99精品一区二区三区无码吞精 | www插插插| 爱豆国产剧免费观看大全剧集 | 中文字幕第九页 | a级黄色影院 | 国产精品国产三级国产普通话对白 | av色播| 男女瑟瑟网站 | 十八禁毛片 | 黄色福利网站 | 日本熟妇毛茸茸丰满 | 国产精品777777| 中文有码一区 | a级片一级片 | 艳妇臀荡乳欲伦交换gif | 久久视频免费看 | 色综合一区二区 | 成人av免费在线播放 | 免费小视频 | 成人手机av | xxxx日本免费 | 欧美黄色激情视频 | 朋友的姐姐2在线观看 | 国产男男gay网站 | 91av国产在线 | 久久美女视频 | 中文字幕精品一区二区三区精品 | 日本免费网址 | 国产三级漂亮女教师 | 97免费视频观看 | 久久r视频 | 久久艹伊人 | 麻豆视频在线免费观看 | 国产精品国产三级国产在线观看 | 又黄又爽又刺激的视频 | 国产私拍视频 | 亚洲欧美日韩中文字幕在线观看 |