ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ViewController Life Cycle
    iOS 2021. 12. 16. 22:02

    안녕하세요.

     

    오늘은 ViewController Life Cycle.

    즉, View Controller 생명 주기를 알아보도록 하겠습니다.

     

    보통 생명주기는 어떠한 시스템이 생겨나고 사라질 때까지의 흐름을 의미합니다.

     

    ViewController 또한 생명주기가 존재합니다

     

    ViewController의 생명 주기 Method들은 아래와 같습니다.

     

    loadView()
    . loadViewIfNeeded()
    . viewDidLoad()
    . viewWillAppear(_ animated: Bool)
    . viewWillLayoutSubviews()
    . viewDidLayoutSubviews()
    . viewDidAppear(_ animated: Bool)
    . viewWillDisappear(_ animated: Bool)
    . viewDidDisappear(_ animated: Bool)

     

    익숙한 친구들도 보이고 생소한 친구들도 보이네요.

     

    지금부터 하나씩 알아보도록 하겠습니다.

     

    참고로 호출되는 순서랑은 상관이 없습니다.


    1. loadView()

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview/

     

    Apple Developer Documentation

     

    developer.apple.com

    viewDidLoad가 가장 먼저 실행되는 줄 알고 계셨던 분들이 많을 거라고 생각합니다.

     

    이 함수는 현재 ViewController의 View가 존재하지 않을 때 호출이 됩니다.

     

    그러니깐 ViewController에서 호출하던 self.view가 이 시점에 만들어집니다.

     

    스토리보드에서 ViewController를 생성하면 만들어지던 view가 이 시점에 할당되는 것입니다.

    만약 self.view를 변경하고 싶다면 이 함수를 overriding 해서 사용하시면 됩니다.

    호출 시점을 확인해보겠습니다.

    loadView가 먼저 불리는 것을 확인할 수 있습니다. 

    view를 load하는 메서드니깐 didLoad보다 먼저 불리는 게 당연하겠네요.

     

    2021.12.22일 수정

    공식 문서에서는 InterfaceBuilder를 사용해서 View를 생성한 경우에는 loadView 메소드를 오버라이드하지 말라고 명시하고 있습니다.

    또한 loadView를 커스텀하게 구현하는 경우에는 super.loadView를 호출하지 말아야 한다고 합니다.

    super.loadView가 아닌 self.view에 UIView를 할당해주어야합니다.


    2. loadViewIfNeeded()

    loadView는 이해했는데 loadViewIfNeeded()는 무엇일까요

     

    일단 호출 시점이 어딘지 확인해보겠습니다.

     

    ?? 호출이 되지 않네요.

    일반적인 친구가 아닌가 봅니다. 

     

    공식 문서를 살펴보겠습니다. 

     

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621446-loadviewifneeded

     

    Apple Developer Documentation

     

    developer.apple.com

    viewController에 view가 없을 때 view를 load 한다고 합니다.

     

    viewController가 화면에 나타나면 view가 무조건 있을 텐데 view가 없는 경우가 있을까 싶었는데요.

     

    억지로 만든 상황이기는 하지만 viewController를 생성하고

    해당 viewController가 화면에 아직 나타나지 않았으면 view가 load 되지 않은 상황입니다. 

     

    이 경우 loadViewIfNeeded를 하면 view가 load 된 것을 확인할 수 있습니다.

     

    근데 아직 개발하면서 이렇게 작성해본 경험은 없습니다..

    view를 미리 로드해서 사용자 경험이 좋아질 수 있을까요??

    혹시 좋은 사례를 아시는 분은 알려주시면 감사하겠습니다.

     

    또 viewWillAppear 테스트하기 위해서 navigationController안에 embed 했더니

    loadViewIfNeeded가 호출되는 현상이 발생했는데 이 또한 아시는 분은 알려주시면 감사하겠습니다. 


    3. viewDidLoad()

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload/

     

    Apple Developer Documentation

     

    developer.apple.com

     

    다음은 매우 익숙한 친구입니다.

    공식문서에서는 뷰 계층이 메모리에 올라가고 나서 호출된다고 합니다. 

     

    ViewController는 프로젝트를 생성하면 기본적으로 만들어져 있습니다.

     

    그 이유는 무조건 호출되기 때문입니다.

     

    뷰가 메모리에 로드된 순간 한 번 딱 한번 호출되는 메서드이기 때문에

    한 번만 호출되기 원하는 초기화 메서드들 같은 경우 여기에 작성하면 되겠습니다.


    4. viewWillAppear(_ animated: Bool)

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear/

     

    Apple Developer Documentation

     

    developer.apple.com

     

    Life Cycle 메서드들은 이름에서 언제 수행되는지 확인할 수 있어서 좋은 것 같습니다. 

     

    viewWillAppear는 view가 나타나기 직전에 호출되는 함수라는 것을 알 수 있습니다.

     

    공식문서에서는 view가 view 계층에 추가되기 직전에 호출된다고 합니다.

     

    메모리에 로드만 되었다고 view가 그려지지는 않습니다.

     

    그 view를 화면에 나타내는 과정도 필요합니다.

     

    근데 왜 메서드의 이름이 loadView처럼 persentView가 아닐까요?

     

    그 이유는 view를 그리는 시점을 확신할 수 없기 때문입니다.

     

    화면 그리고 기기의 성능에 따라서 view를 그리는 속도가 달라집니다.

     

    그래서 view를 보여주기 시작할 시점과 view를 모두 보여준 시점을 알려주는 겁니다. 

     

    viewWillAppear의 호출 시점을 알아보도록 하겠습니다. 

     

     

    화면이 여러 개 존재해야 viewWillAppear을 확인하기 쉽습니다.

     

     

    위와 같이 코드를 작성하고 실행시켜보겠습니다.   

    viewDidLoad가 실행된 후 viewWillAppear가 호출되는 것을 볼 수 있습니다.

    이후 노랑 View로 돌아갔다가 오면 viewWillAppear만 호출되는 것을 확인할 수 있습니다.

     

    view가 보이는 시점마다 실행시키고 싶은 메서드를 정의해주면 되겠습니다.


    4. viewDidAppear(_ animated: Bool)

    짝꿍인 viewDidAppear를 확인해보겠습니다.

     

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621423-viewdidappear/

     

    Apple Developer Documentation

     

    developer.apple.com

    view가 모두 그려지고 난 후에 view가 나타났음을 알려주는 메서드입니다. 

     

     view가 view 계층에 추가되고 나서 호출됩니다.

     

    이런 식으로 viewDidAppear를 오버라이딩했습니다.

     

    viewWillAppear이후에 viewDidAppear가 호출되는 것을 확인할 수 있습니다.

     

    viewWillAppear와 viewDidAppear사이에서 열심히 view를 그리고 있기 때문에 약간의 텀이 존재합니다.

     

    view가 완전히 그려진 시점을 보장될 때 동작해야 하는 메서드들을 작성하면 됩니다.


     

    5. viewWillDisappear(_ animated: Bool)

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621485-viewwilldisappear/

     

    Apple Developer Documentation

     

    developer.apple.com

    viewWillDisappear는 view가 사라질 때 호출되는 메서드입니다.

     

    공식문서에서는 view가 view 계층에서 없어지기 전에 불린다고 말하고 있습니다.

     

    마찬가지로 두 viewController에 위와 같이 코드를 추가하겠습니다.

     

    view가 사라질 때마다 호출되는 것을 확인할 수 있습니다.

     

    viewWillAppear만으로는 감이 확실히 오지 않으니 viewDidDisappear와 함께 살펴보도록 하겠습니다.


    6. viewDidDisappear(_ animated: Bool)

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621477-viewdiddisappear

     

    Apple Developer Documentation

     

    developer.apple.com

     

    view가 view 계층에서 제거되었음을 알려주는 메서드입니다.

     

    willDisappear 다음에 didDisappear가 실행되는 것을 확인할 수 있습니다.

     

    추가적으로 설명드릴 거는 앱이 foreground와 background로 가는 것은 appear와 disappear를 호출하지 않습니다.


    7. viewWillLayoutSubviews()

    이제 마지막 짝꿍들만 남았습니다.

     

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621437-viewwilllayoutsubviews

     

    Apple Developer Documentation

     

    developer.apple.com

     

    이 메서드는 viewController의 뷰가 하위 뷰들을 배치하기 직전에 호출되는 메서드입니다.

     

    view의 bounds가 변경되면 하위 view들의 위치가 변경되기에 이 메서드가 호출됩니다. 

     

    ViewWillAppear와 ViewDidAppear 사이에서 View가 그려진다고 했으니

    View의 bounds도 그 사이에 정해집니다.

     

    따라서 View의 bounds가 정해진 시점에 viewWillLayoutSubview가 호출되므로

    viewWillAppear와 viewDidAppear사이에서 호출되는 것입니다.

     

    bounds가 변경되는 대표적인 경우가 바로 화면을 회전시키는 경우입니다. 

     

    회전시킬 때마다 viewWillLayoutSubviews가 호출되는 것을 확인할 수 있습니다.


    8. viewDidLayoutSubviews()

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621398-viewdidlayoutsubviews

     

    Apple Developer Documentation

     

    developer.apple.com

     

    viewDidLayoutSubviews는 view의 하위 뷰들이 배치가 완료되면 호출되는 메서드입니다.

     

    하지만 하위 뷰의 하위 뷰들의 배치가 완료되었다는 것은 보장할 수 없습니다.

     

    viewWillLayoutSubviews와 viewDidLayoutSubviews는 사실 self.view.layoutSubviews 직후로 불립니다. 

     

    그런데 self.view.subview.layoutSubviews는 self.viewDidLayoutSubviews가 호출된 후에 불립니다.

     

    레이아웃은 superview부터  subview로 진행됩니다.

     

    이렇게 UIlabel에 layoutSubviews를 오버라이딩하고

     

    실행시키면 

     

    viewDidLayoutSubviews후에 UILabel이 layoutSubviews를 호출하는 것을 확인할 수 있습니다.

     

    이상으로 View Controller의 생명 주기를 알아보았습니다.

     

    실행시키고자 하는  메서드가 어느 시점에 불려야 하는지를 판단하는 것이 중요하다고 생각됩니다.

     

    오늘은 여기까지 하겠습니다.

     

    'iOS' 카테고리의 다른 글

    Hugging & Compression Resistance  (0) 2021.12.21
    ARC(Automatic Reference Counting)  (0) 2021.12.20
    View  (0) 2021.12.15
    Delegate Pattern  (0) 2021.12.14
    iOS 개발하는데 실제 디바이스가 필요할까?  (0) 2021.12.14
Designed by Tistory.