오늘은 iOS View Life Cycle에 대해서 알아보려 한다.
Android를 공부할 때도 처음에는 Life Cycle에 대해서 배우는데 그때 이리저리 로그를 꽂아서 어떤 순서로 동작하는지 공부했던 게 생각나서 오늘은 그렇게 공부해보려 한다.
Android든 iOS든 생명 주기에 대해서는 다들 중요하게 다루는 데는 이유가 있다.
뭐 사실 나는 기본을 그렇게 중요하게 쌓았던 개발자는 아니라서...
(엄청나게 고생도 하고 필요성을 많이 느껴서 지금이라도 쌓기 위해 노력 중...)
처음에 생명 주기에 대해서 보면
그래그래 이렇게 동작하는 거 알겠어! 근데 어쩌라고?
라는 느낌이다.
프로젝트가 복잡하지 않으면 생명 주기를 고려하지 않고도 프로그램이 잘 돌아갈 수 있다.
내가 겪었던 여러 상황에 대해서 말하자면
등등과 같은 여러 상황을 겪었었다. (예시보다 복잡한 상황들도 있었음...)
그때는 생명주기에 대해서 다시 차분하게 짚고 넘어가야 하는 시기라는 걸 무시하고 임시방편으로 잘 고쳐 나갔었다.
이젠 다시는 그런 일을 겪고 싶지도 않고, 잘 알고 싶어 정리하는 포스팅이다.
이름에서 알 수 있듯 View가 생기고 사라지는거에 대한 주기이다.
View Life Cycle에 대해 공부하면 위와 같은 그림을 볼 수 있다.
위의 그림으로 하나씩 주기를 살펴보자
(init은 나중에 따로 다뤄보고)
로그를 통해 생명 주기에 대해서 알아보기로 했으니 아래의 사진처럼 각각의 주기에 해당하는 Method에 print로 로그를 꽂았다.
프로젝트를 실행하면
다음과 같은 로그가 찍히는걸 확인할 수 있다.
위의 로그에서 loadView
가 가장 먼저 호출됨을 확인했다.
그렇다면 loadView
의 역할은 무엇일까?
loadView
는 viewController 관리하는 View를 만드는 역할을 한다.
(ViewController에 대해서도 포스팅해야겠다...)
loadView
는 viewController의 view 프로퍼티가 현재 nil일때 호출된다.
호출된 loadView
는 view를 로드하거나 생성하고 생성된 view를 viewController의 view 프로터피에 지정한다.
outlet들과 action들이 이 Method에서 생성되고 연결된다.
내가 위에
view 프로퍼티에 지정한다.
라고 썼는데 view 프로퍼티를 통해view.backgroundColor = UIColor.blue
위와 같은 코드를 사용할 수 있게된다.
(이 코드는 두번째 view의 background를 바꿔주는 코드)
(와우... 색깔 선정... 무슨 일이야...)
1: '이동' 버튼으로 첫번째 화면에서 두번째 화면으로 이동
2: Back 버튼으로 두번째 화면에서 첫번째 화면으로 이동
3: '이동' 버튼으로 첫번째 화면에서 두번째 화면으로 이동
우선 위의 사진을 통해 유추할 수 있는건
- 첫번째 화면에 NavigationBar가 있으니 첫번째 화면은 UINavigationController로 이뤄져 있다.
- 이 게시물에서 UINavigationController는 Stack으로 구성되어 있다고 했다.
loadView()
가 호출된다.loadView()
가 호출된다.push
된다.pop
된다.deinit
로그가 찍혔다.loadView()
로그가 찍히지 않는다.loadView()
가 호출된다.If you use Interface Builder to create your views and initialize the view controller, you must not override this method.
(출처: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview)
라고 Apple 문서에 써져 있다.
storyboard나 .xib 파일로 만들어지는 경우가 아닌 직접적으로 코딩하여 view를 만드는 경우를 제외하고서는 loadView
를 override하지 않는 것이 좋다고한다.
위의 코드는 loadView
를 override해서 view를 직접 만들어주는 코드이다.
위의 코드처럼 직접 코딩해서 view를 만드는 경우는 override하지 말라는 것이다.
loadView만 써도 벌써 이만큼... 오늘도 간단하게 쓰고 넘어가려했는데... 왜 나는 그것이 안되는가...
viewDidLoad
가 생명 주기에서 가장 익숙한 Method가 아닐까 싶다.
Called after the controller's view is loaded into memory.
(출처: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload)
라고 Apple 문서에 써져 있다.
viewController의 view가 메모리에 로드된 직후에 호출되는 Method다.
즉, loadView
에서는 view를 생성하고 구성해 메모리에 올리는 거고,
viewDidLoad
는 view가 메모리에 올라간 직후에 호출되는 것이다.
view에 추가적인 작업을 하고 싶다면 이 Method에서 하면 된다.
Notifies the view controller that its view is about to be added to a view hierarchy.
(출처: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear)
라고 Apple 문서에 써져 있다.
(view hierarchy 부분은 나중에 다룰거니 일단은 이런게 있구나 하면 될거 같다..)
viewWillAppear(_:)
는 view가 이제 화면에 나타날거라고(Notifies) 알려주는 Method이다.
즉, view가 화면에 나타나기 직전에 호출된다.
(viewDidLoad
가 호출된다고 화면에 view가 보이는 것이 아니다.)
view가 화면에 어떻게 보여질지 보여지기 전에 추가할 수 있다.
viewDidAppear
는 이름에서 알 수 있듯 view가 화면에 나타났다고 알려주는 Method이다.
(애니메이션을 시작하거나 비디오나 음악을 재생할 수 있다.)
viewWillDisappear(_:)
는 view가 사라지기 직전에 호출되는 Method이다.
(여기서 키보드를 숨기는 것과 같은 처리를 할 수 있다.)
view가 사라진 직후에 호출되는 Method이다.
(여기서 notification을 듣는거를 멈출 수 있다.)
우리는 view의 Life Cycle에 대해서 알아봤다.
위의 사진에서 다른 점을 찾은 사람!🙋♀️
왼쪽에서는
viewWillDisappear
, viewDidDisappear
가 호출된다.viewWillAppear
, viewDidAppear
가 호출된다.오른쪽에서는
viewWillDisappear
, viewDidDisappear
가 호출되지 않는다.viewWillAppear
, viewDidAppear
가 호출되지 않는다.왼쪽은 Navigation 방식으로 "2. 두번째" 화면을 호출했을때의 로그이고, (아래 사진에서 왼쪽)
오른쪽은 modal 방식(fullScreen이 아닌)으로 "2. 두번째" 화면을 호출했을때의 로그이다. (아래 사진에서 오른쪽)
위의 사진에서 보면 왼쪽에서는 "1. 첫번쨰" view가 화면에서 보이지 않는다.
하지만 오른쪽에서는 "1. 첫번째" view가 "2. 두번째" view 뒤에 조금 보이고 있다.
즉, 우리에게 보여지는 화면에서 view가 보이는지 안 보이는지에 따라
viewWillDisappear
,viewDidDisappear
가 호출된다.
- 짧은 애니메이션이 사용자에게 보이지 않음 혹은 애니메이션의 중간부터 보게됨
- 다른 view에 갔다 다시 올 때 자꾸 view가 초기화됨
왜 이런 일이 생겼을까?
viewDidLoad()
에서 애니메이션이 실행되도록 코드를 짰기 때문이다.
viewDidLoad()
는 view가 메모리에 로드되었을때 호출되는 Method이다.
그러므로 viewDidLoad()
가 호출되었다고 해당 view가 사용자에게 보이는 것이 아니다.
그래서 짧은 애니메이션을 viewDidLoad()
에서 실행하면 화면에 해당 view가 보여지게 되는 동안 애니메이션이 끝나버리게 된다.
이 부분은 다양한 이유가 있을 수 있는데 다른 view로 이동했다 돌아올때 appear Method들이 다시 호출되므로 이 부분에 대해서 적절한 조치가 취해지지 않아서 그랬다.
View Life Cycle은 이쯤에서 마무리해야겠다.
오늘도 간단하게 포스팅하려 했지만 길어진 포스팅...
하지만 아직... 다룰게 많다...ㅋㅋㅋ
언제나처럼 틀린 부분 지적과 궁금한 부분은 언제든 환영합니다.👋