iOS

iOS) ViewController Life Cycle

snowe 2021. 2. 14. 23:24

오늘은 iOS개발을 하면 할수록 굉장히 중요한 개념이라는 것을 느끼게 해주는 뷰의 생명주기에 대해 알아보겠습니다.

 

App이 실행되면서 여러 event들에 의해 화면이 나오고 사라지는데, 이 과정 속에서 ViewController는 자신들만의 생명주기를 갖습니다.

 

출처(https://subscription.packtpub.com)

 

개인적으로 중요하다고 생각한 부분은 하이라이팅 하였습니다!

1. init(coder:)

storyboard 를 통해 View Controller들을 만들 경우 View Controller의 객체가 생성될 때 초기화 작업을 하는 메소드.

이 메소드에서 초기화 작업을 할 때 View Controller들은 그들의 lifetime동안 필요한 자원들을 할당받게 된다. 

아직 이 시점에서는 View Controller의 View가 생성된 것이 아니기 때문에 View의 요소들에 대한 접근을 시도한다면 에러가 발생한다.

(많이 겪어봄)

 

2. init(nibName:bundle:)

storyboard가 아닌 분뢰된 .nib파일로 관리될 경우 init(coder:)대신 이 메소드를 초기화의 용도로 사용할 수 있다.

 

3. loadView()

화면에 띄워줄 View를 만드는 메소드, Outlet & Action이 여기서 생성되고 연결된다.

storyboadr나 .nib파일의 사용 없이 모든 것을 코드로 작성하는 것이 아닌 이상 

직접 호출(override)하지 않는 것을 권장한다.

 

4. viewDidLoad()

개발을 시작하면 가장 먼저 흔하게 접할 수 있는 viewDidLoad()

loadView() 덕분에 Outlet & Action이 이미 메모리에 위치하고 있기 때문에 보통 화면이 로드되기 전 백그라운드 단계에서 처리하는것이 좋은 작업들이 위치한다(네트워크 호출 or 리소스의 초기화 or 초기화면 구성)

주의 viewDidLoad()는 LifeCycle상에 딱 한번만 있기 때문에 한 번만 있을 행위에 대해서만 작성하는 것이 좋다.

값이 지속적으로 변해야 하는 작업은 다른 곳에서 이루어져야 한다.

 

5. viewWillAppear(_:)

뷰가 로드 된 후, 하지만 뷰가 아직 화면에는 나타나기 전에 호출된다.

UI내의 애니메이션을 실행시키거나, 비디오나 소리를 재생하는 행위, 그리고 뿌려지는 데이터의 업데이트를 수행할 수 있다.

 

주의

또한 처음 뷰가 띄워질 때에는 viewDidLoad()가 먼저 호출되지만, 다른 뷰로 이동했다가(push, present) 다시 이 화면으로 돌아 올 때에는 viewWillAppear()부터 호출이 된다(글 밑에 그림 참조).

나도 앱잼 기간 동안 개발하면서 알게 된 사실

 

6. viewDidAppear(_:)

뷰가 완전히 화면에 나타난 후. 여기에 코드를 작성하면 사용자가 값이 변화되는 것을 시각적으로 볼 수 있다.

 

7. didReceiveMemoryWarning()

이 메소드가 호출 된 것을 종종 보곤 했는데 어떤 역할을 하는지에 대해서는 잘 알지 못했다.

 

뭔데?

컴퓨터의 경우 메모리가 부족하면 메모리의 데이터를 하드디스크로 옮긴다. 하지만 iOS의 경우 기기별 제한적인 메모리를 가지고 있기 때문에 만약 메모리 부족 현상이 생긴다면 앱이 죽어버리는 대참사가 발생할 것이다.

바로 그 대참사를 막아주는 역할을 하는것이 didReceiveMemoryWarning() 메소드이고, 메모리 부족에 대한 위험을 미리 알려줌으로써 몇몇 메모리를 미리 해제해주는 등의 조치를 취해줄 수 있다.

 

8. viewWillDisappear

다음 View Controller 화면으로 전환되기 전 혹은 View Controller 가 사라지기 직전에 호출되는 메소드

 

9.viewDidDisappear

뷰가 화면에서 완전히 사라지고 나서 호출되는 메소드

notification을 듣는 행위를 멈추기, 다른 객체의 속성을 observing하는것을 멈추기, 디바이스의 센서를 점검하거나 네트워크를 호출하는 행위들은 화면이 사라지고 나서는 필요 없는 작업들입니다.

화면이 사라지고 나서 필요없어지는 (멈춰야하는) 작업들을 여기서 할 수 있다. 

 

10. deinit()

View Controller가 메모리에서 사라지기 전 호출된다.

이 메소드를 할당 받은 자원 중 자동 참조 계수(Automatic Reference Counting, 일명 ARC)에 의해 해지가 불가능한 자원들을 해제하기 위해 override 할 수 있다. 또한 백그라운드에서 돌리기 위해 이전의 메소드에서 멈추지 못하였던 행위들을 이 메소드 내에서 멈출 수 있다.

뷰가 화면에서 사라지는 것이 메모리에서 해지되는 것을 의미하지 않음!
많은 Container View Controller들이 그들의 View Controller들을 메모리에서 유지하고 있으므로 유의할 것.
화면에서 사라진 View Controller들이 정상적으로 작동하고 여전히 notification 을 받을 수 있음

 

다음은 UINavigationController의 push, pop 과정이다.

 

UINavigationController의 경우 View가 push되어 들어오면 스택에 쌓아두고 pop하면 스택에서 꺼내는 방식을 사용하는데 UINavigationController의 pop의 경우 우측의 사진처럼 자동으로 deinit()을 해주니 이 점도 기억해두면 좋을 것 같다!

push의 경우 뷰 위에 또 다른 뷰가 올라오는 것이기 때문에 deinit()이 호출 되지 않음(좌측 사진)

UINavigationController의 push, pop 과정

 

 

 

참조한 글

이동건의 이유있는 코드-1

이동건의 이유있는 코드-2