【发布时间】:2021-07-28 13:54:42
【问题描述】:
我的应用程序正在泄漏模型对象,因为对象保留了保留视图本身的闭包。
最好举个例子来说明。
在下面的代码中,Model 在ContentView 消失后不会被释放。
//
// Content View is an owner of `Model`
// It passes it to `ViewB`
//
// When button is tapped, ContentView executes action
// assigned to Model by the ViewB
//
struct ContentView: View {
@StateObject private var model = Model()
var body: some View {
VStack {
Button(action: {
model.action?()
}) {
Text("Tap")
}
ViewB(model: model)
}
.frame(width: 100, height: 100)
.onDisappear {
print("CONTENT DISAPPEAR")
}
}
}
struct ViewB: View {
@ObservedObject var model: Model
var body: some View {
Color.red.frame(width: 20, height: 20)
.onAppear {
//
// DANGER:
// Assigning this makes a leak and Model is never deallocated.
// This is because the closure is retaining 'self'
// But since it's a struct, how can we break the cycle here?
//
model.action = { bAction() }
}
}
private func bAction() {
print("Hey!")
}
}
class Model: ObservableObject {
var action: (() -> Void)?
deinit {
print("MODEL DEINIT")
}
}
我不确定为什么这里会出现某种保留周期。 由于 View 是一个结构体,所以在闭包中引用它应该是安全的,对吧?
【问题讨论】:
-
我会让模型成为可选的和
@ObservedObject,而不是状态对象。我认为这会解决你的问题。