[英]SwiftUI retain cycle in view hierarchy
我有以下具有保留周期的視圖層次結構,這是我可以重現問題的最簡單方法。 所有視圖模型和屬性都必須保留,因為它們在原始解決方案中是需要的:
import SwiftUI
struct MainView: View {
@StateObject var viewModel = MainViewModel()
var body: some View {
NavigationView { [weak viewModel] in
VStack {
Button("StartCooking") {
viewModel?.show()
}
if viewModel?.isShowingContainerView == true {
ContainerView()
}
Button("StopCooking") {
viewModel?.hide()
}
}
}
.navigationViewStyle(.stack)
}
}
final class MainViewModel: ObservableObject {
@Published var isShowingContainerView = false
func show() {
isShowingContainerView = true
}
func hide() {
isShowingContainerView = false
}
}
struct ContainerView: View {
@Namespace var namespace
var body: some View {
VStack {
SubView(
namespace: namespace
)
}
}
}
struct SubView: View {
@StateObject var viewModel = SubViewModel()
var namespace: Namespace.ID
var body: some View {
Text("5 min")
.matchedGeometryEffect(id: UUID().uuidString, in: namespace)
.onTapGesture {
foo()
}
}
private func foo() {}
}
final class SubViewModel: ObservableObject {}
如果我運行應用程序,點擊StartCooking
,然后點擊StopCooking
並檢查 memory 圖,我仍然看到SubViewModel
的實例,這意味着此代碼中存在泄漏。 如果我刪除:
NavigationView
或ContainerView
的 VStack 或者matchedGeometryEffect
或tapGesture
保留周期已解決。 不幸的是我需要所有這些。 您能看出問題可能是什么以及如何解決嗎?
看起來像一個 SwiftUI 錯誤。 一種可能的解決方法(如果子視圖是一個或有限的集合)是使用視圖 model 工廠來提供實例。
這是一個視圖的示例:
struct SubView: View {
@StateObject var viewModel = SubViewModel.shared // single instance !!
// .. other code
}
final class SubViewModel: ObservableObject {
static var shared = SubViewModel() // << this !!
}
我可以通過在 SubViewModel 中使每個屬性都是可選的並在SubViewModel
消失時運行SubView
來解決它,這使它們成為nil
。 SubViewModel
仍然停留在 memory,但不會占用那么多空間。
有趣的是,我什至嘗試將 viewmodel 設為可選,並在視圖消失時將其設為 nil,但它仍然停留在 memory。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.