UIViewController(視圖控制器)想必大家都不會陌生,開發中常常會用到。這次講講它的生命周期。
1,視圖的生命周期
說是 ViewController 的生命周期,其實指的是它控制的視圖(View)的生命周期。每當視圖的狀態發生變化時,視圖控制器會自動調用一系列方法來響應變化。
通過這些方法,我們就可以跟蹤到視圖的整個生命周期。各個方法按執行順序排列如下:
(1)init:初始化程序
(2)loadView:視圖初始化
這個方法不應該被直接調用,而是由系統自動調用。它會加載或創建一個 view 並把它賦值給 UIViewController 的 view 屬性。
同時重寫 loadView 方法的時候,不要調用父類的方法。
(3)viewDidLoad:視圖加載完成,但還沒在屏幕上顯示出來
我們可以重寫這個方法,對 view 做一些其他的初始化工作。比如可以移除一些視圖,修改約束,加載數據等。
(3)viewWillAppear:在視圖即將顯示在屏幕上時調用
我們可以在這個方法裡,改變當前屏幕方向或狀態欄的風格等。
(4)viewDidApper:在視圖顯示在屏幕上時調用時調用
我們可以在這個方法中,對視圖做一些關於展示效果方面的修改。
(5)viewWillDisappear:視圖即將消失、被覆蓋或是隱藏時調用
(6)viewDidDisappear:視圖已經消失、被覆蓋或是隱藏時調用
(7)viewVillUnload:當內存過低時,需要釋放一些不需要使用的視圖時,即將釋放時調用
(8)viewDidUnload:當內存過低,釋放一些不需要的視圖時調用。
注意:自 iOS6 起,viewWillUnload 和 viewDidUnload 這兩個方法被廢除了。當系統發出內存警告的時候,會自動把 view 給清除掉,不用我們再特別處理。
同時系統還會調用 didReceiveMemoryWarning 方法通知視圖控制器,我們可以在這裡面進行一些操作,來釋放一些額外的資源。(通常來說不用操作,比較最占資源的 view 已經被系統給清理了。)
2,視圖狀態的轉換
在實際應用中,視圖通常不會按照上面列的流程一次執行下來,可能會在可見與不可見的狀態間互相轉換。比如一開始視圖是可見的,接著我們跳轉到另一個 ViewController,這時原來視圖就變成不可見的。後面我們又跳轉回來,那麼這個視圖就又是可見的。
當視圖的可見性發生變化時,視圖控制器對應的方法也會隨之響應。具體可見下圖:
特別要注意的是:Appearing 和 Disappearing 這兩個狀態是可以互相轉化的。
3,測試樣例說明
(1)ViewController 是首頁視圖控制器,我們將裡面所有的與生命周期有關的函數都打印出來。
(2)同時 ViewController 中添加了一個“跳轉”按鈕,點擊後跳轉到另一個視圖控制器(AnotherViewController)。
(3)AnotherViewController 裡有個“返回”按鈕,點擊又會回到前一個頁面。
4,測試代碼
(1)ViewController.swift
import UIKit
class ViewController: UIViewController {
//視圖初始化
override func loadView() {
super.loadView()
print("loadView")
}
//視圖加載完成
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad")
//創建跳轉按鈕
let button:UIButton = UIButton(type: .System)
button.frame=CGRectMake(10, 50, 100, 30)
button.setTitle("跳轉", forState: .Normal)
button.addTarget(self,action:#selector(jump),forControlEvents:.TouchUpInside)
self.view.addSubview(button);
}
//視圖將要出現的時候執行
override func viewWillAppear(animated: Bool) {
print("viewWillAppear")
}
//視圖顯示完成後執行
override func viewDidAppear(animated: Bool) {
print("viewDidAppear")
}
//視圖將要消失的時候執行
override func viewWillDisappear(animated: Bool) {
print("viewWillDisappear")
}
//視圖已經消失的時候執行
override func viewDidDisappear(animated: Bool) {
print("viewDidDisappear")
}
//收到內存警告時執行
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//跳轉到另一個視圖
func jump(){
print("點擊按鈕,開始跳轉!")
let anotherVC = AnotherViewController()
presentViewController(anotherVC, animated: true, completion: nil)
}
}
(2)AnotherViewController.swift
import UIKit
class AnotherViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//創建返回按鈕
let button:UIButton = UIButton(type: .System)
button.frame=CGRectMake(10, 150, 100, 30)
button.setTitle("返回", forState: .Normal)
button.addTarget(self,action:#selector(back),forControlEvents:.TouchUpInside)
self.view.addSubview(button);
}
//返回之前視圖
func back(){
print("點擊按鈕,開始返回!")
self.dismissViewControllerAnimated(true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
5,運行測試
我們從 ViewController 跳到 AnotherViewController,再從 AnotherViewController 跳回 ViewController。整個控制台打印出