-1

I have this simple example app. Why deinitializer is not being called on a Observable Object view model after the next screen is presented?

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView(contentViewModel: ContentViewModel())
        }
    }
}

class ContentViewModel: ObservableObject {
    deinit {
        print("deinit")
    }
}

struct ContentView: View {
    @ObservedObject var contentViewModel: ContentViewModel
    @State var toPresentNext: Bool = false
    var body: some View {
        Text("Hello, world!")
            .padding()
            .onTapGesture {
                toPresentNext = true
            }.fullScreenCover(isPresented: $toPresentNext) {
                ContentView1()
            }
    }
}
  • Because `@main struct TestApp` still holds a reference to it for the life of the app. – Yrb May 09 '22 at 00:20
  • @Yrb So, is it expected behaviour for ObservableObjects to not being deintialized while app runs? – asking questions May 09 '22 at 16:33
  • The long answer is here: [Automatic Reference Counting](https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html). The short answer is as long as some object has a reference to that `ObservableObject`, it will not be deinitialized. In this case, your `@main` has the reference. This is the first object created, and the last to be destroyed. As long as it exists, so will `ContentViewModel`. – Yrb May 09 '22 at 18:06

1 Answers1

0

struct is value type where as class is reference type (See Is Swift Pass By Value or Pass By Reference to know what this means).

So basically you don't make reference of a ContentView object and it's objects doesn't gets passed around. It rather makes copies of itself. So only way for deinit to be called is when all the copies of struct or ContentView goes out of scope.

N4SK
  • 525
  • 7
  • 24