初始化视图内的@ObservedObject时发生内存泄漏

问题描述 投票:0回答:1

我有一个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")
                }
            }
        }
    }
}

ios swift swiftui
1个回答
0
投票

它看起来没有泄漏。这是我的视图设置(在屏幕上添加了标题,以方便参考-代码在解释之后)。

从导航

User Setup-> Contact Related-> Add Contact

然后一直返回主屏幕User Setup,然后导航到下一个屏幕将释放先前创建的视图模型实例。注意:我在模型中添加了唯一ID,该ID在初始化和取消初始化模型时会打印ID。

This leads me to believe that Models being observed are not deinited as soon as the view that is using it is getting released.  Swift runtime controls when the observable model should be released.  Also when I did the profiling for abandoned memory, I did not see any increase in the memory growth.  Also when the previously instance of the view model is getting released, there is a dip in the memory which proves the point that it is getting deallocated at that moment.   
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")

    }
}

通常,我不会在结构内添加可观察视图模型的定义。

© www.soinside.com 2019 - 2024. All rights reserved.