Featured image of post UIViewController 생명주기(lifecycle methods - View State Method)

UIViewController 생명주기(lifecycle methods - View State Method)

오늘은 UIViewController의 생명주기에 대해 알아보자.

그러려면 먼저 UIViewController가 어떤 녀석인지 알아봐야겠지..

UIViewController

An object that manages a view hierarchy for your UIKit app.

애플 문서에서는 UIKit 앱에서 계층 구조를 관리하는 객체라고 설명되어 있다.

모든 앱에는 적어도 하나의 UIViewController가 있고 UIViewController는 view를 관리하고, 다른 UIViewController로 전환하거나 view와 사용자 상호 작용을 관리한다.

아카이브 된 애플문서를 보면 UIViewController가 뷰 계층을 어떻게 관리하는지 더 잘 나와있다.

img

view가 변경되면 ViewController 자동으로 자신의 메소드를 호출하여 하위 클래스가 변경사항에 응답할 수 있도록 하는데, 뷰가 보여지고(Appear), 사라지는(Disappear) 일련의 과정들을 생명주기라고 한다.

img

애플 문서에 나와있는 이 그림에서는 ViewController가 view의 시각적 상태를 어떠한 메소드를 활용하여 관리하는지 보여준다. will로 시작하는 메소드는 변화가 시작되기 전, did로 시작하는 메소드는 변화가 끝난 후 라고 이해할 수 있겠다. 애플의 Naming 칭찬해 👏

뭔가 순환하는 듯한 애플의 이미지가 잘 이해가 가지 않는다면 이 그림을 보자

img

출처: https://subscription.packtpub.com/book/application-development/9781783550814/6/ch06lvl1sec60/uiviewcontroller-lifecycle-methods

loadView

Creates the view that the controller manages.

컨트롤러가 관리하는 뷰를 만들어주는 메소드이다. view property를 할당하여 뷰를 로드하거나 만들어주는 역할을 한다.

스토리보드나 xib와 같은 interfaceBuilder를 사용하는 경우 nib 파일을 로드하여 자동으로 호출되고, 코드로만 뷰를 구성할 경우 오버라이드 하여 사용해야 한다.

viewDidLoad

Called after the controller’s view is loaded into memory.

컨트롤러의 뷰가 메모리에 로드되었을때 호출된다고 정의되어 있다.

뷰가 프로그래밍 방식으로 생성되었든지, xib 파일에서 로드되었는지 여부와 상관없이 뷰와 뷰 계층이 메모리에 로드되었을 때 호출된다. 화면에 만들어 질 때 한번만 호출되기 때문에 리소스를 초기화하거나 초기화면을 구성하는 용도로 사용된다.

img 새로운 코코아터치 파일을 만들면 보이는 이것! viewDidLoad()
Do any additional setup after loading the view. 부분에 코드를 넣어주면 된다.

viewWillAppear

Notifies the view controller that its view is about to be added to a view hierarchy.

뷰가 뷰 계층에 추가될 것이라고 뷰 컨트롤러에게 알리고 뷰를 보여주기 위해 화면을 그리는 동작 이전에 호출된다.

For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented.

화면이 보여지기 전 변경되어야 할 작업들(상태바의 방향(Depth표시 등))을 여기서 먼저 처리하고 뷰를 그려주면 되겠다.

viewDidAppear

Notifies the view controller that its view was added to a view hierarchy.

뷰 컨트롤러에게 뷰가 추가되었음을 알리는 메소드이다.

If a view controller is presented by a view controller inside of a popover, this method is not invoked on the presenting view controller after the presented controller is dismissed.

💡 popover 내부에서 뷰 컨트롤러가 표시되는 경우 표시된 컨트롤러가 해제되고 보여지는 뷰 컨트롤러에서도 호출되지 않는다.

viewWillDisappear

Notifies the view controller that its view is about to be removed from a view hierarchy.

뷰 컨트롤러에게 뷰가 제거될 것임을 알리는 메소드이다. 뷰가 실제로 제거되기 전과 애니메이션이 구성되기 전에 호출된다.

For example, you might use this method to revert changes to the orientation or style of the status bar that were made in the viewDidAppear(_:) method when the view was first presented.

이 뷰를 처음 표시할 때 viewDidAppear 메소드에서 처리한 변경된 작업들을 되돌리고 싶은 경우 여기서 처리하면 된다.

viewDidDisappear

Notifies the view controller that its view was removed from a view hierarchy.

뷰 컨트롤러에게 뷰가 제거되었음을 알리는 메소드이다. 뷰가 실제로 제거된 후에 호출된다.

생각해보기

❓ 만약에 홈화면에서 버튼을 클릭하여 다른 화면으로 이동했다가 다시 홈화면으로 돌아오는 경우에는 이렇게 되는 것일까?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//App 실행되고 FirstVC 노출
1. FirstVC loadView
2. FirstVC viewDidLoad
3. FirstVC viewWillAppear
4. FirstVC viewDidAppear

//push로 SecondVC 호출
5. SecondVC loadView
6. SecondVC viewDidLoad
7. FirstVC viewWillDisappear
8. SecondVC viewWillAppear
9. FirstVC viewDidDisappear
10. SecondVC viewDidAppear

//다시 FirstVC로 돌아오는 경우(Pop)
11. SecondVC viewWillDisappear
12. FirstVC viewWillAppear
13. SecondVC viewDidDisappear
14. FirstVC viewDidAppear

15. Optional("Second") 해제됨 // SecondVC deinit 실행

10번 이후에 loadView()viewDidLoad()가 없는 이유는 FirstVC는 현재 네비게이션 컨트롤러의 rootView이기 때문에 앱 실행 시 한번만 호출된다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
//App 실행되고 FirstVC 노출
1. FirstVC loadView
2. FirstVC viewDidLoad
3. FirstVC viewWillAppear
4. FirstVC viewDidAppear

//present로 SecondVC 호출
5. SecondVC loadView
6. SecondVC viewDidLoad
7. SecondVC viewWillAppear
8. SecondVC viewDidAppear

//다시 FirstVC로 돌아오는 경우(Dismiss)
9. SecondVC viewWillDisappear
10. SecondVC viewDidDisappear

11. Optional("Second") 해제됨  // SecondVC deinit 실행

present Modality를 사용해서 뷰 컨트롤러를 호출하는 경우, SecondVC만 로드되어 호출되고 FirstVC는 아래쪽에 남아있어 Dismiss될 때 FirstVC의 viewWillDisappear viewDidDisappear가 호출되지 않는다.

Reference

Apple - UIViewController
Apple - View Controller Programming Guide for iOS
Apple - loadView()
Apple - viewDidLoad()
Apple - viewWillAppear(_:)
Apple - viewDidAppear(_:)
Apple - viewWillDisappear(_:)
Aplle - viewDidDisappear(_:)
Zedd - View Controller의 생명주기
ViewController의 LifeCycle