我有一个ViewModel
类,它是一个ObservableObject
,我在初始化它的对应视图时初始化它。如果我在视图中有任何绑定到ViewModel
,那么ViewModel
就会被泄露。
例如,如果我在工作表中显示上述视图,则每次显示工作表时,都会分配一个新的引用,当工作表被取消时,它不会被释放。参考计数一直在增长,就像我提交纸张的次数一样。
我是遗漏了什么,还是@ObservedObject
属性包装器不应该以这种方式使用?
这是一个简单的例子,展示了这个问题。从未为deinit
调用ViewModel
函数
struct NewContactView: View {
class ViewModel: ObservableObject {
@Published var firstName = ""
@Published var lastName = ""
@Published var email = ""
@Published var phoneNumber = ""
init() {
print("INIT")
}
deinit {
print("DEINIT")
}
}
@ObservedObject private var viewModel = ViewModel()
var didCreateNewContact: (Contact) -> Void = { _ in }
var body: some View {
NavigationView {
Form {
Section(header: Text("Names")) {
TextField("First Name", text: $viewModel.firstName)
TextField("Last Name", text: $viewModel.lastName)
}
Section(header: Text("Details")) {
TextField("Email", text: $viewModel.email)
TextField("Phone Number", text: $viewModel.phoneNumber)
}
Button(action: {}) {
Text("Save")
}
}
}
}
}
编辑:添加了显示工作表的代码
struct ContactsListView: View {
@EnvironmentObject var contactStore: ContactStore
@State private var isCreatingNewContact = false
var body: some View {
List(contactStore.contacts) { contact in
ContactListItem(contact: contact)
}
.navigationBarItems(trailing: Button(action: { self.isCreatingNewContact = true }) {
Image(systemName: "plus")
})
.sheet(isPresented: $isCreatingNewContact) {
NewContactView(didCreateNewContact: self.createNewContactHandler)
}
}
private func createNewContactHandler(_ contact: Contact) {
contactStore.contacts.append(contact)
isCreatingNewContact = false
}
}
编辑2:内存图截图
编辑3:奇怪的是,用VStack替换表单视图可以消除漏洞。如果我使用List视图而不是VStack,泄漏就会回来.
发布于 2021-08-11 18:10:25
使用@StateObject,以便它只插入一次,用于iOS 14
永远不要这样做:@ create私有var viewModel = ViewModel(),它将一直创建视图模型。您需要在应用程序开始时创建该对象,并将其传递到不能重新创建的位置,或者可以在某些视图中创建,因为仪表板取决于应用程序结构。
发布于 2019-11-17 11:48:21
看上去没有漏水。这是我的视图设置(添加标题以便于参考-代码是在解释之后)。
驶离
User Setup
-> Contact Related
-> Add Contact
然后返回到主屏幕User Setup
,然后导航到下一个屏幕,释放先前创建的视图模型实例。注意:我在模型中添加了唯一的id,当模型被输入和退出时,它会打印id。
这让我相信,当正在使用它的观点被发布时,被观察到的模型就不会被发现。Swift运行时控制何时应该发布可观察的模型。另外,当我对废弃的内存进行分析时,我没有看到内存增长的任何增长。另外,当先前的视图模型实例被释放时,内存中有一个dip,这证明了此时它正在被释放。
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: ContactRelated() ) {
Text("Contact Related")
}
Spacer()
}
.navigationBarTitle("User Setup")
}
}
}
struct ContactRelated: View {
var body: some View {
VStack {
NavigationLink(destination: NewContactView() ) {
Text("Add New Contact")
}
Spacer()
}
.navigationBarTitle("Contact")
}
}
struct NewContactView: View {
class ViewModel: ObservableObject {
var id = UUID()
@Published var firstName = ""
@Published var lastName = ""
@Published var email = ""
@Published var phoneNumber = ""
init() {
print(">>>init \(id)")
}
deinit {
print(">>>deinit \(id)")
}
}
@ObservedObject private var viewModel = ViewModel()
//var didCreateNewContact: (Contact) -> Void = { _ in }
var body: some View {
Form {
Section(header: Text("Names")) {
TextField("First Name", text: $viewModel.firstName)
TextField("Last Name", text: $viewModel.lastName)
}
Section(header: Text("Details")) {
TextField("Email", text: $viewModel.email)
TextField("Phone Number", text: $viewModel.phoneNumber)
}
Button(action: {}) {
Text("Save")
}
}
.navigationBarTitle("Add Contact")
}
}
通常,我不会在结构中添加可观察视图模型的定义。
发布于 2020-01-01 13:05:00
好像是个虫子。使用ScrollView代替列表对我有效。
https://stackoverflow.com/questions/58897709
复制相似问题