SwiftUI父/子视图内存泄漏:是预期行为还是框架Bug?
问题分析:SwiftUI内存泄漏原因及结论
这不是SwiftUI的Bug,是代码中存在闭包循环引用导致的预期内存泄漏。
泄漏原因
- 创建
ChildView时传入的onHide闭包捕获了ContentView的overlayVisible状态(用于修改它),该闭包被ChildView持有。 ChildView的@StateObject标记的ChildViewStore是ObservableObject,SwiftUI会将其生命周期与ChildView绑定。- 闭包捕获了与
ContentView相关的状态引用,ChildView又持有该闭包,形成循环引用链:ChildViewStore→ChildView→onHide闭包 →ContentView的状态引用,导致ChildViewStore在ChildView被移除后无法正常释放。
修复方案
方案1:打破闭包强捕获
修改ContentView中创建ChildView的代码,对状态绑定进行弱捕获:
ChildView(onHide: { [weak binding = $overlayVisible] in guard let binding = binding else { return } withAnimation { binding.wrappedValue = false } })
方案2:改用Binding传递状态(更符合SwiftUI模式)
重构ChildView,用Binding替代闭包传递状态,从根源避免循环引用:
// 修改ChildView定义 struct ChildView: View { @Environment(\.presentationMode) var presentationMode @StateObject var store: ChildViewStore = ChildViewStore() @Binding var isVisible: Bool var body: some View { Color.gray .ignoresSafeArea(.all) .overlay{ VStack { Button("Dismiss") { presentationMode.wrappedValue.dismiss() withAnimation { isVisible = false } } } } } } // 在ContentView中调用 ChildView(isVisible: $overlayVisible)
内容的提问来源于stack exchange,提问作者ramden
相关产品推荐
相关产品推荐

