I've got a problem with an object not being destroyed when put into the environment and used with a NavigationView
. If a view creates an object, creates a NavigationView
and inserts the object into the environment, then when that view disappears the object should be deallocated, but it's not.
The example app below should demonstrate this issue!
Look at the LoggedInView
where the ViewModel
is created: When the user logs out, the LoggedInView
disappears, but the deinit of ViewModel
is not called.
What needs to change so that the ViewModel
is deinitialized when the LoggedInView
disappears?
Here is an example I've created to demo the issue:
struct ContentView: View {
@State private var loggedIn = false
var body: some View {
if loggedIn {
LoggedInView(loggedIn: $loggedIn)
} else {
Button("Log In") {
loggedIn = true
}
}
}
}
struct LoggedInView: View {
@Binding var loggedIn: Bool
@StateObject private var viewModel = ViewModel()
var body: some View {
NavigationView {
Button("Log Off") {
loggedIn = false
}
}
.environmentObject(viewModel)
}
}
class ViewModel: ObservableObject {
@Published var name = "Steve"
private let uuid = UUID().uuidString
init() {
print("initing " + uuid)
}
deinit {
print("deiniting " + uuid)
}
}
If I comment out either the NavigationView {
or the .environmentObject(viewModel)
then the ViewModel
is deallocated as expected.
If I log in and out a few times the console looks like this:
initing 5DA78F23-6EC7-4F06-82F8-6066BB82272E
deiniting 5DA78F23-6EC7-4F06-82F8-6066BB82272E
initing 5BEABAF1-31D0-465E-A35E-94E5E141C453
deiniting 5BEABAF1-31D0-465E-A35E-94E5E141C453
initing 7A4F54FA-7C32-403B-9F47-1ED6289F68B5
deiniting 7A4F54FA-7C32-403B-9F47-1ED6289F68B5
However, if I run the code as above then the console looks like this:
initing D3C8388D-A0A0-42C9-B80A-21254A868060
initing 8DFFF7F7-00C4-4B9F-B592-85422B3A01C0
initing F56D4869-A724-4E10-8C1A-CCA9D99EE1D3
initing ED985C33-C107-4D8C-B51D-4A9D1320F784
deiniting 8DFFF7F7-00C4-4B9F-B592-85422B3A01C0
initing CCD18C41-0196-44B0-B414-697B06E0DE2F
deiniting ED985C33-C107-4D8C-B51D-4A9D1320F784
initing EAA0255A-5F2E-406D-805A-DE2D675F7964
initing 49908FAA-8573-4EBE-8E8B-B0120A504DDA
What's interesting here is that the User
object does sometimes get deallocated but it seems only after it's created multiple instances and it never seems to deallocated the first few that were created.