Memory leak in SwiftUI environment on Xcode 14.1 ?

Xcode 14.1 is showing a strange memory behavior for the SwiftUI environment for me.

Please consider the following example

import SwiftUI

@main
struct DoubleCheckApp: App {
    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(EnvObj())
        }
    }
}

class EnvObj: ObservableObject {
    init() { print("INIT") }
    deinit { print("DEINIT") }
}

struct ContentView: View {
    @State var sel: Int = 0

    var body: some View {
        VStack {
            Picker(selection: $sel, label: Text("JLPT")) {
                ForEach(0..<3, id: \.self) { idx in
                    Text("\(idx)").tag(idx)
                }
            }.pickerStyle(.segmented)
        }
    }
}

This will output

INIT
INIT
DEINIT
INIT

essentially leaving two instances of EnvObj instantiated.

Removing the scenePhase or the Picker implementation will result in a normal INIT/DEINIT pattern. This does not happen on Xcode 13.4.1. I couldn't test on any other versions, yet.

Accepted Reply

What happens if you put

@StateObject var env = EnvObj()

above your App's body declaration and pass env on to ContentView?

In your code EnvObj() my be called multiple times because body may be evaluated every time SwiftUI needs it.

  • Thank you! Somehow I thought I already checked that. I shouldn't post "bugs" late at night 😓

Add a Comment

Replies

What happens if you put

@StateObject var env = EnvObj()

above your App's body declaration and pass env on to ContentView?

In your code EnvObj() my be called multiple times because body may be evaluated every time SwiftUI needs it.

  • Thank you! Somehow I thought I already checked that. I shouldn't post "bugs" late at night 😓

Add a Comment