안녕하세요.
그동안 대충은 알고 있었던 SwiftUI의 View Lifecycle에 대해서 정확하게 알고 가는 시간을 가져볼게요.
개인적으로 Lifecycle 개념도 중요하지만, Lifecycle이 정확하게 언제 호출되는지 (ex. 렌더링 전? 뷰 계층 제거된 후?)도 중요하다고 생각하기 때문에 로그 찍어보면서 하나씩 살펴보려고 합니다.
(관련 공식 문서가 별로 없더라구요.. 그래서 추측성 분석이 될 수도 있을 것 같아요ㅠ)
# Lifecycle method
## onAppear
View가 보이기 전에 action을 수행하는 함수입니다.
View가 첫 렌더링 되기 전에 action 클로저가 끝나는 것을 보장합니다.
그래서 아래처럼 onAppear에 수행시간이 오래 걸리는 action을 등록하면, 그만큼 화면이 늦게 출력됩니다.
(2초 sleep이 끝난 이후에 화면이 출력되는 것을 볼 수 있어요.)
## task
iOS 15 이상부터 사용할 수 있는 함수입니다.
View가 보이기 전에 비동기 task를 수행하는 함수입니다.
비동기 task이기 때문에 task가 끝나기 전에 View가 그려질 수 있습니다.
또한, task가 끝나기 전에 View가 사라지게 되면(disappear) 자동으로 task를 취소(cancel) 시킵니다.
아래 예시를 보면 View가 보이고 나서 task가 완료되는 것을 볼 수 있습니다.
추가로 task 함수에는 task(id:priority:_:) 라는 함수도 존재합니다.
이 함수는 View가 보이기 전 뿐만 아니라 Equatable 프로토콜을 준수하는 특정 변수의 값이 변할 때에도 task를 수행시킵니다.
(아래 예시를 보면 toggle 할 때마다 task가 수행됩니다.)
그리고 만약 task가 완료되기 전에 값이 바뀌게 된 경우, 기존 task를 cancel 시키고 새로운 task를 수행합니다.
## onDisappear
View가 사라지고 난 이후에 action을 수행하는 함수입니다.
(예시는 생략할게요..ㅎ..)
# 여러 가지 궁금한 거 알아보기
이제부터, 개인적으로 궁금한 것들 직접 호출해 보면서 확인해 볼게요.
## onAppear와 task 중 먼저 호출되는 것은?
결론
- 판단할 수 없다.
- 테스트했을 땐 항상 onAppear가 먼저 호출되긴 하지만, onAppear가 먼저 호출된다고 장담할 수 없다.
## Navigation 이동(push, pop)할 때 onAppear, onDisappear가 호출될까?
결론
- NavigationView 자체는 onAppear만 호출된다. (새로운 화면이 push 되어도 NavigationView의 onDisappear는 호출되지 않는다.) (만약 NavigationView 자체가 사라지는 경우에는 onDisappear가 호출된다.)
- 부모 View 위에 자식 View를 push 했을 때 자식 View의 onAppear가 호출되고 부모 View의 onDisappear가 호출된다.
- 자식 View가 pop 됐을 때, 부모 View의 onAppear가 호출되고 자식 View의 onDisappear가 호출된다.
## TabBar 이동했을 때 onAppear, onDisappear가 호출될까?
결론
- TabBar 터치로 인해 화면 이동했을 때 이전 View에선 onDisappear가, 보여질 View에선 onAppear가 호출된다.
## fullScreenCover로 View를 덮으면 onDisappear가 호출될까?
결론
- fullScreenCover로 View가 덮여도 onDisappear는 호출되지 않는다.
- fullScreenCover로 인해 View가 다시 보여도 onAppear는 호출되지 않는다.
## UIKit의 viewWillAppear와 SwiftUI의 onAppear를 같이 사용하면 어떻게 될까?
결론
- viewDidLoad가 제일 먼저 호출된다.
- viewWillAppear, onAppear 모두 호출된다. (순서는 보장할 수 없을 듯..)
# 참고
- https://developer.apple.com/documentation/swiftui/view/onappear(perform:)
- https://developer.apple.com/documentation/swiftui/view/task(priority:_:)
- https://developer.apple.com/documentation/swiftui/view/ondisappear(perform:)
이번 글은 여기서 마무리.
'SwiftUI' 카테고리의 다른 글
TCA(1) : ReducerProtocol, StoreOf, WithViewStore (0) | 2023.06.13 |
---|---|
TCA(0) : The Composable Architecture 개요 (0) | 2023.06.07 |
overlay + matchedGeometryEffect로 Hero Anmiation 비슷하게 만들기 (0) | 2023.05.24 |
커스텀 LabelStyle (0) | 2023.03.28 |
RoundedCornerStyle (0) | 2023.03.26 |