[SwiftUI] Observable Object 초기화 트랩
Observable Object 초기화 시 처리
SwiftUI
와 ObservableObject
는 거의 모든 상황에서 함께 사용한다.논리를 ObservableObject
에 통합함으로써 SwiftUI
측의 코드를 간결하게 유지할 수 있다.본론입니다.
ObservableObject
초기화할 때 (init할 때) 어떤 처리를 하셨습니까?나의 경우, 때때로 Combine
등으로 수용 값을 쓰는 처리를 한다.
class DetailViewModel: ObservableObject {
@Published var items: [String] = []
private let someManager: SomeManager = .shared //シングルトン
private var cancellations = Set<AnyCancellable>()
init() {
debugPrint("[DetailViewModel]init")
someManager.$data
.receive(on: DispatchQueue.main)
.sink { [weak self] data in
debugPrint("fetch data")
self?.items = data.map({ $0.text })
}.store(in: &cancellations)
}
func fetchData() {
someManager.fetchData()
//->データが取得され、someManager.dataが更新されるとします
}
}
이 코드는 보기에 문제가 없는 것 같다.NavigationLink와 함께 사용하는 경우
다음
NavigationLink
도 응용 프로그램을 구축하는 상황을 고려해야 한다.
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink("Detail", destination: DetailView())
}
}
}
struct DetailView: View {
@ObservedObject var viewModel = DetailViewModel()
var body: some View {
VStack {
Text("DetailView")
Text(viewModel.items.join(","))
Button("fetch data", action: { viewModel.fetchData() })
}
}
}
ContentView
에서 마이그레이션 대상을 선택합니다.DetailView
에서 데이터를 가져오고 표시합니다.바람직한 행위와 실제적인 행위
이러한 구성의 경우
DetailView
ObservableObject
로 이전하면 초기화DetailViewModel
가 기대된다.그러나 실제로
ContentView
가 표시되는 단계DetailViewModel
에서도 초기화된다.왜 그랬을까?아래의 보도를 참고하였다.
이 글에 따르면
SwiftUI
의 행동으로 설정된NavigationLink
의destination
View가 곧 초기화되었다.아마 이것은 버그가 아니라 그런 방법일 것이다대책
이것
SwiftUI
의 행동에서 두 가지 대책을 고려했다.주의 행동으로
ObservableObject
초기화할 때 처리onAppear
2에 대해서도
onAppear
가 여러 번 호출될 가능성을 고려해야 한다.
Reference
이 문제에 관하여([SwiftUI] Observable Object 초기화 트랩), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/usk2000/articles/168cd07711929c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)