안녕하세요 이누입니다!
여러분은 ViewController의 Life Cycle에 대해 잘 알고 계신가요? 저는 잘 알다가도 헷갈리거나 모르는 부분이 등장해서 당황스러울 때가 많더라구요. 그래서 오늘은 이를 포함해 전체적인 ViewController의 Life Cycle에 대해 정리해보았습니다.
(2022.03.16 내용수정)
가장 먼저 init에 대해 정리하려고 살펴보니 nib, xib 파일에 대한 언급이 있더라구요. 그래서 이 부분부터 정리하고 넘어갑니다.
cf. nib란?
- nib : NeXT Interface Builder (binary 기반), 인터페이스 빌더에서 생성한 객체들을 저장하는 파일입니다. UI를 구성하는 객체들과 이들의 세부설정, 각 객체들간의 관계 등을 포함합니다.
- xib : XML Interface Builder (text 기반), 인터페이스 빌더로 작업한 결과는 xib형태로 저장되고 빌드 시점에 nib로 변경, 앱 번들에 복사되고 런타임에 로드됩니다. xib는 text 기반의 파일인 만큼 nib 파일보다 소스 컨트롤 및 읽기에 용이합니다.
Init
ViewController의 초기화를 진행하면 내부의 객체들을 초기화하하는 작업이 수행됩니다. 하지만 아직 내부의 View들이 생성된 것은 아니기 때문에 내부 View 요소에는 접근할 수 없습니다.
init(coder:)
: 스토리보드를 기반으로 ViewController를 만들 경우 사용합니다.init(nibName: bundle:)
: nib 파일을 기반으로 View Controller를 만들 경우 사용합니다.
loadView
loadView()
는 View Controller가 사용자가 설정한 View를 자신의 최상위 View로 설정하는 과정입니다. 이는 ViewController가 무엇을 기반으로 호출되었는가(코드, 스토리보드, nib)와 관계없이 호출됩니다. 이 때 내부적으로 instantiateWithOwner()
라는 메서드가 실행되면서 필요한 subView들을 nib으로부터 unarchiving하고 subView 객체들이 ViewController와 연결되게 됩니다. (이 때 subView 객체들은 로드가 끝나자마자 awakeFromNib()
을 호출합니다. subView들은 ViewController가 아니기 때문에 바로 내부 객체들에 접근할 수 있습니다.) 이렇게 연결이 완료되면 ViewController는 viewDidLoad()
를 호출하여 view들에 대한 load가 완전히 종료되었음을 알립니다.
viewDidLoad ~ deinit
viewDidLoad()
: 필요한 뷰의 정보들이 모두 메모리에 위치되면 호출됩니다. 따라서 필요한 데이터를 갱신하는 코드를 작성할 수 있습니다. 이는 ViewController의 생애중 오직 한번 호출되므로 한번만 수행하고 싶은 행위를 처리하기에 적절합니다.viewWillAppear()
: ViewController의 뷰가 화면에 나타나기 직전에 호출됩니다. 화면이 나타날때마다 호출되므로 다른 뷰에서 돌아올 때 수행하고 싶은 행위들에 대해 처리하기 좋습니다.viewDidAppear()
: ViewController의 뷰가 모두 화면에 나타나면 호출됩니다. 주로 UI의 애니메이션을 실행시키거나 비디오 및 소리를 재생시키거나 데이터의 업데이트를 수행합니다. API로부터 정보를 받아와 화면을 업데이트하는 로직을 위치시키기 적당합니다.viewWillLayoutSubviews()
: view의 bounds를 정하는 단계입니다. UIView의layoutSubviews()
메서드가 트리거되기 직전에 호출됩니다.viewDidLayoutSubviews()
:layoutSubviews()
메서드 호출 후에 호출됩니다. subview들의 size와 position, constraint들이 적용이 완료된 상태입니다.viewWillLayoutSubviews()
와viewDidLayoutSubviews()
는 가로모드 혹은 세로모드가 되면서 screen의 방향이 변화될 때도 호출됩니다. View의 bounds에 대한 재계산이 필요할때마다 두 메서드가 모두 호출됩니다.viewWillDisappear(_:)
: 다른 ViewController로 화면이 전환되면서 원래 ViewController가 사라질 때 호출됩니다. 일반적으로 이 함수를 override 해서 처리해야 할 작업은 거의 없다고 합니다.viewDidDisappear(_:)
: ViewController가 화면에 사라지고나면 호출됩니다. Container View Controller를 사용하다보면 여러 ViewController가 메모리에 유지됩니다. 즉, 화면에서 사라진 ViewController도 여전히 notification 등의 이벤트를 받을 수 있다는 것입니다. 따라서 주로 여기서 notification 취소, observing 취소, 디바이스 점검 등을 수행해줍니다.deinit()
: ViewController 객체가 메모리에 사라지기 전 호출됩니다. 주로 할당받은 자원 중 ARC에 의해 해제가 되지 않는 자원을 해제하기 위해 override합니다. 화면에서 사라진다고 해당 메서드가 호출되는 것은 아님에 주의해야 합니다.
cf. didReceiveMemoryWarning
- 메모리가 부족해지면 호출됩니다.
- 이를 관리해 필요없는 메모리를 해제하는 작업을 할 수 있습니다.
- iOS가 강제로 애플리케이션을 종료하는 것을 방지하기 위해 필요합니다.
참고
- https://developer.apple.com/documentation/objectivec/nsobject/1402907-awakefromnib
- https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview
- https://stackoverflow.com/questions/17400547/awakefromnib-outlets-and-storyboards-is-the-documentation-wrong#answer-37191391
- https://velog.io/@yohanblessyou/%EC%8A%A4%ED%86%A0%EB%A6%AC%EB%B3%B4%EB%93%9C%EC%9D%98-%EC%9A%94%EC%86%8C%EA%B0%80-Nib%EC%9D%B4-%EB%90%98%EB%8A%94-%EA%B3%BC%EC%A0%95-feat.-awakeFromNib
- https://candost.blog/view-lifecycle-in-ios/
'🍎 Apple > UIKit' 카테고리의 다른 글
[UIKit] UITableView 기초부터 다시 살펴보기 (2) | 2022.04.17 |
---|---|
[UIKit] View Drawing Cycle (0) | 2022.03.16 |
[UIKit] Multiple Gesture Recognizer 처리하기 (0) | 2022.02.05 |
[UIKit] Compositional Layout Example from Apple Sample Code (2) (0) | 2022.01.18 |
[UIKit] Compositional Layout Example from Apple Sample Code (1) (4) | 2022.01.17 |