1. 현상
현상은 iOS 16.0 이상에서 List, VStack 등 내부에서 ForEach를 통해 여러 뷰를 생성할 때 실제로는 뷰가 두 번씩 init된다는 것이다.
이렇다보니 뷰 생성 시 수행하는 로직이 있었는데 해당 로직이 불필요하게 2배씩 호출되는 이슈가 있었다. (body에는 한 번만 진입한다)
2. 샘플 코드 및 결과
아래는 간단하게 코드와 해당 코드의 실행 결과이다.
struct ContentView: View {
var numbers: [Int] = Array(1...10)
var body: some View {
VStack {
ForEach(self.numbers, id: \.self) { number in
NumberView(number: number)
}
}
.padding()
}
}
struct NumberView: View {
var number: Int
init(number: Int) {
self.number = number
print("🔴 Init > NumberView \(number)")
}
var body: some View {
let _ = print("🔵 Draw > NumberView \(self.number) body")
Text("NumberView - \(self.number)")
}
}
iOS 15.5 | iOS 16.1 |
![]() |
![]() |
3. 해결(못함ㅋ)
원인을 발견하지는 못했다. iOS 버전에 따라 달라지는 걸 보니 애플 버그인가 싶기도하고..
단, WWDC21 Demystify SwiftUI 영상을 참고해보니 SwiftUI에서 view value의 lifetime을 제어하는 것은 불가능하다는 것을 알 수 있었다. view value는 일시적이므로 여기에 의존해서는 안되고, view identity에 의존해야한다.
여기에 더해서, SwiftUI View fundamentals 글에서 "view init 단계에서 뭘 하지 마라" 라고 한다..!
4. 결론
아직은 UIKit가 좋은듯..ㅎ
'SwiftUI' 카테고리의 다른 글
[SwiftUI] UICollectionView + SwiftUI 뷰 혼용해서 사용하기 (1) | 2023.08.22 |
---|