ViewController와 Lifecycle
- UIKit
- Swift
- MVC
View controllers | Apple Developer Documentation
“You use view controllers to manage your UIKit app’s interface. A view controller manages a single root view, which may itself contain any number of subviews. User interactions with that view hierarchy are handled by your view controller, which coordinates with other objects of your app as needed. Every app has at least one view controller whose content fills the main window. If your app has more content than can fit onscreen at once, use multiple view controllers to manage different parts of that content.”
- 공식 문서에서 말하는 View Controllers에 대한 설명
”UIKit 앱의 인터페이스는 _뷰 컨트롤러_가 관리합니다. 뷰 컨트롤러는 하나의 _루트 뷰__를 관리하며, 그 안에는 여러 개의 서브뷰가 포함될 수 있습니다. 사용자 상호작용은 이 뷰 계층에서 처리되고, 뷰 컨트롤러는 필요에 따라 앱의 다른 객체들과 조율합니다. 모든 앱에는 메인 윈도를 채우는 최소 하나의 뷰 컨트롤러가 존재합니다. 만약 화면에 한 번에 다 담을 수 없는 콘텐츠가 있다면, 여러 뷰 컨트롤러를 사용해 각각의 부분을 관리합니다.”
- GPT에게 중요 사항만 번역해달라고 한 결과_
UIViewController란?
UIViewController | Apple Developer Documentation
View Controller Programming Guide for iOS: The Role of View Controllers
Displaying and managing views with a view controller | Apple Developer Documentation
UIKit에서 사용되는 UIViewController는 iOS의 화면(View) 계층을 관리하는 핵심 객체 이다.
-
ViewController는 UIKit 기반 앱에서 하나의 화면(1개의 View 계층)을 관리하는 객체
-
UIViewController의 인스턴스를 직접 생성하는 것이 아닌, 상속받아 화면 컨트롤러를 구현한다.
import UIKit // UIViewController을 상속받아 구현한다! class HangulClockViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } } -
⭐ UI와 데이터의 연결, 사용자와의 상호작용 처리, 다른 VC와 화면 전환 관리, 레이아웃 관리, 메모리 관리 등 엄청나게 많은 역할을 수행하는
핵심이다!
📌 ViewController의 주요 역할
- 뷰 계층 관리
- ViewController(이하 VC로 통일)는 현재 화면에 표시되는 모든 UIView들(버튼이나 레이블 등..)과 계증 구조를 관리한다.
- UI와 데이터 연결
- MVC 아키텍처 기준으로 Controller의 역할을 수행한다.
- 데이터(Model)와 뷰(View) 사이의 흐름을 관리한다.
- 이벤트 처리 및 사용자 상호작용 관리
- 사용자의 터치나 버튼 탭 등 다양한 이벤트를 직접 관리한다.
- 화면 전환 및 컨테이너 관리
- 여러 화면을 전환(navigation, modal, tab 등)하거나 여러 VC를 포함하는 컨테이너의 역할(SplitView나 TabBar와 같은)을 수행한다.
- 메모리 및 리소스 관리
- 메모리 부족 등 상황에 따라 뷰를 해제하거나 복구한다.
📌 ViewController의 생명주기(Lifecycle) 혹은 상태 변화
UIKit는 ViewController의 생명주기를 정말.. 엄청나게 엄격히 관리한다.
대표적으로 viewDidLoad, viewWillAppear, viewDidAppear , viewWillDisappear 등이 존재한다.


ViewController의 생명주기는 뷰의 생성, 화면 표시, 숨김, 소멸 관리 과정을 메서드로 정의한다.
이때 will 콜백(화면 변화 전)과 did 콜백(화면 변화 후) 는 짝을 이루며 부적절한 해제나 재설정 방지를 위해 각 시점에 맞는 올바른 처리를 해야한다.
ViewController의 생명주기는 위 사진과 같은 흐름을 가진다.
- View 생성 시
- init
- loadView
- viewDidLoad
- viewWillAppear
- viewDidAppear
- View 종료 시
- viewWillDisappear
- viewDidDisappear
📌 ViewController의 주요 생명주기 흐름 메서드
- init(coder:)
- 스토리보드를 통해 VC를 생성할 경우 VC의 객체가 생성될 때 초기화 작업을 수행하는 메서드
- 객체를 ByteStream으로 바꿔 저장하거나, 기타 의도한 작업이 없다면 NSCoder는 무시해도 상관 X
- ⭐ 해당 시점에서는 View가 생성된 게 아니므로 View에 접근하면 크래시난다.
1-1. init(nibName:bundle:)
- 스토리보드가 아니라 따로 분리한
.nib파일로 관리할 경우 init(coder:) 대신 활용한다.
- loadView()
- 컨트롤러의 view 계층을 직접 생성할 때 오버라이드 하는 메서드
- 본격적으로 화면에 출력될 View를 만드는 메서드이다.
- 보통은 직접 호출하지 않고 UIViewController가 내부적으로 필요 시점에 호출
- 스토리보드나
.nib파일로 만들어지는 경우가 아닌모두 직접적으로 코드를 작성하는 경우를 제외하곤, override하지 않는 것이 좋다. outlet과action들이 생성되고 연결되는 시점이다.
- viewDidLoad()
- 뷰 계층이 메모리에 적재된 직후
오직 1회 호출 - ViewController의 생명주기 중 오직 단 한 번만 호출된다.
- ⭐ 주기적으로 데이터가 변경되거나 이와 유사한 행위들은 다른 메서드에서 정의할 것
- 해당 메소드가 호출되는 시점에 outlet들은 이미 메모리에 위치한 상태
- 실질적으로 사용자에게 화면을 보여주기 전 데이터를 뿌려주기 위한 코드를 작성할 수 있음
- 보통 화면이 보여지기 전, 백드라운드에서 처리해야하는 작업들을 해당 시점에서 연결하면 좋음
- 네트워크 호출, 데이터 셋업, UI 초기화 등등..?
- viewWillAppear(_:)
- ViewController의 View가 올라가기 직전에 호출
- 뷰가 화면에 올라가기 직전에 호출(매번 화면 진입 시 반복)
- 화면 갱신, 애니메이션 준비 등 뷰가 보이기 직전 작업을 삽입
- 앱이 실행되고 첫 View가 출력될 때 호출되는 것은 viewDidLoad()와 동일하지만, 화면 전환을 통해 다시 현재의 화면으로 돌아올 때도 호출된다.
- viewDidAppear(_:)
- 뷰가 실제 화면에 그려진 직후 호출
- 네트워크 요청 시작, 애니메이션 실행 등 실질적인 뷰 노출 후 동작에 사용
- didReceiveMemoryWarning()
- iOS 기기들은 제한된 메모리 크기를 가지고 있다.
- 메모리가 부족하면 메모리를 스왑하는 작업을 하지 않는다.
- 위 메서드는 ViewController가 자원 관리를 수행하고 있는 동안 메모리 한계 경고 알람을 해당 메서드를 통해 탐지할 수 있도록 해준다.
- 즉, 메모리 경고를 받을 때 호출된다.
- viewWillDisappear(_:)
- 뷰가 사라지기 직전(다른 화면 전환 등) 호출되는 메서드
- 상태 저장, 애니메이션 중단 등 작업에 사용
- viewDidDisappear(_:)
- 뷰가 완전히 사라진 후 호출되는 메서드
- 리소스 정리, 타이머 무효화 등 해제 작업을 수행할 때 사용
- deinit
- VC가 메모리에서 사라지기 전 호출되는 메서드
- 할당한 자원 중 ARC에 의해 해지가 불가능한 자원들을 해제하기 위해 override 할 수 있다.
- 비동기 작업 및 리소스 해제를 담당
- ⭐ VC가 화면에서 사라지는 것이 메모리에서 해지되는 것을 의미하지 않는다.
- VC 컨테이너들은 VC들을 메모리에서 유지한다.
- Navigation Controller를 예시로 들면 이전에 화면에 보인 VC들은 여전히 메모리에 남아있다.
- View Hierarchy 내에서 Back을 수행하는 경우만 사라진 VC들을 메모리에서 해제한다.
🤔 의문점.
ViewDidLoad는 UIViewController를 상속받은 클래스가 생성될 때 실행되는걸까?ViewDidLoad는 클래스가 생성될 때 실행되는 것이 아닌, 클래스의 뷰가
로드되었을 때호출된다.
_persentViewController_나popToViewController같은 메서드들이 호출된 다음에 호출되며, 클래스가 생성됐더라도present등의 방식으로 해당 클래스의 뷰가 메모리에 로드되지 않는다면, _viewDidLoad__는 호출되지 않는다.
이외에 다양한 메서드들
- viewWillLayoutSubviews(), viewDidLayoutSubviews()
- 레이아웃이 갱신되는 시점마다 호출되는 메서드이다.
- Auto Layout이나 뷰 배치 코드를 동적으로 적용할 때 활용하는 메서드이다.