---
# System prepended metadata

title: Swift題目 - ViewController 在 ViewController 裡面的生命週期

---

# Swift題目 - ViewController 在 ViewController 裡面的生命週期

```
請自行填入你找到的答案
演講前請記得說，這東西有可能隨著 iOS 版本不同而不同(事實)，現在這個是 iOS14 的狀況
```

## 單一 ViewController 的生命周期

Q: 從 `init()` 到 `viewDidLoad(:)` 之間，還有幾道方法會被呼叫?

`hint: VC 都有包一個 view，所以 view 會走過的的生命週期都會走過`
1道: loadView()

init(): 初始化ViewController，做關於ViewController，而不是關於view的事
> system can unload views to save memory, it will leave the UIViewController alone. Any properties set in the init methode will not be applied again, since the UIViewController is already initialized
> ViewController load view lazily
> 從storyboard載入ViewController，會呼叫instantiateViewController(withIdentifier:)
> 使用nib載入ViewController，會呼叫init(nibName:bundle:)

[loadView()](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview): 建立view的層級，把root View 指定為view controller的view 
> 若有nib，view會從nib載入；若沒有會自動建立一個空白的UIView

viewDidLoad(:): 只會被呼叫一次，載入ViewController裡的view

![](https://i.imgur.com/lWn3f22.png)

參考: 
1. [NS for iOS Devs — View Lifecycle](https://medium.com/developermind/ns-for-ios-devs-view-lifecycle-82c7723d315c)
2. [探究 UIViewController 生命周期](https://github.com/kingcos/Perspective/issues/22)

Q: 一個 ViewController 的 `init()` 方法，有幾種?在哪些情況下會走哪一種?
1. 從storyboard載入ViewController，會呼叫[instantiateViewController(withIdentifier:)](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init)，使用init(coder:)來創造一個新的ViewController
2. 使用nib載入ViewController，會呼叫[init(nibName:bundle:)](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init)
3. code會呼叫[init(nibName:bundle:)](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init)

Q: 如果你畫面上有一個 tableView，在 `viewDidLoad(:)` 結束後，你將 dataSource 設定好，然後 reloadData()，請問會經過哪些生命週期?

[reloadData()](https://developer.apple.com/documentation/uikit/uitableview/1614862-reloaddata): 調用此方法可以重新加載所有建構表的所有數據，包含其 cell、section header、section footer 以及其 index arrays 等等。為了提高效率，TableView 僅重新檢視可見的行。如果表因為重新加載而縮小，它會調整偏移量。

若是在viewDidLoad，會經過viewDidAppear
已經走到viewDidAppear，則還是停留在viewDidAppear

//補充，有人實現屬於[tableView的生命週期](https://www.jianshu.com/p/64c76a587450)XD

Q: 呈上， `cellForRowAt` 會被呼叫幾次?

當前可見的cell次數

> 補充
> tableView裡面存在兩個數據結構
> - visibleCells 存放當前可見的cell實體
> - reuseCells 存放暫存的cell實體
> 初始繪製時，tableView透過顯示的大小、row的高度、header與footer的高度，來計算要顯示的範圍內容。調用cellForRow(at:)將
> 示範圍內的cell繪製出來，並把這些cells存放在visibleCells
> 
> 螢幕滾動或是呼叫reloadData後，會觸發tableView重新繪製與回收:
> 1. 將不在螢幕上顯示的cells放入reuseCells中，並將其hide
> 2. 通過cellForRow(at:)獲取要顯示的cells，並將是否複用的權力交給develper，一般developer開發時，會先調用dequeueReusableCell取得可以複用的cell
> 3. dequeueReusableCell: 先從visibleCells裡面找相同Id的cell實體，找不到或是用完了，就會從reuseCells裡面找想同Id的cell實體，若還是找不到，則會返回nil，由developer直接建立
> 4. tableView將會將繪製過程中，通過cellForRow(at:)取得的cell放入visibleCells中
> 5. tableView的繪製都在layoutSubviews()中完成。
> 參考: [由TableView的reloadData和reloadSections想出去。。。](http://bigbro.wang/2018/03/TableView%E7%9A%84reloadData%E5%92%8CreloadSections/)

## 複數個 ViewController 的交互行為 - NavigationController

#### rootVC: A
#### 被推進來的 VC: B

Q: 如果 UIWindow 的 rootVC 是 NavigationController，請問 NavigationController 的 生命週期還有 A 的生命週期順序是?


Q: 如果把 B 推進 A，請問 A 和 B 的生命週期順序是?

Q: 如果把 B pop 出 A，請問 A 和 B 的生命週期順序是?

Q: 如果用程式的方式，把 A、B 順序直接調換，生命週期會怎麼呈現?

## 複數個 ViewController 的交互行為 - PageViewController

#### 第一個 VC: A
#### 第二個 VC: B

Q: 如果 UIWindow 的 rootVC 是 NavigationController，請問 NavigationController 的生命週期還有 A 的生命週期順序是?

Q: 如果用 scroll 的方式，把 B 滑入 A，請問 A 和 B 的生命週期順序是?

Q: 如果用 button 點擊，然後用程式的方式直接換頁，請問 A 和 B 的生命週期順序是?

## 複數個 ViewController 的交互行為 - ScrollView 包 ViewController

#### ScrollView 在 rootViewController 裡面
#### 第一個在 ScrollView 的 ViewController: A
#### 第二個在 ScrollView 的 ViewController: B

Q: 請問 scrollView 顯現的時候 A 和 B 的生命週期順序?

## iOS 13 以上的 present

#### rootViewController: A
#### 被 present 的 ViewController: B

Q: present mode 不同的時候， A 會有不同的狀況，請問哪些 mode 會有 `viewWillDisappear(:)`?

