Freezing bug in NavigationLink

I found a very strange bug while using SwiftUI, and the following code is the minimum required to reproduce it. When I press the 'Go to page2' button, the CPU load goes to 100% and the memory usage keeps increasing. What's wrong with this code? I tried to search for a day but could not find any answer.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            Page1()
                .environmentObject(Foo())
        }
    }
}

class Foo: ObservableObject {
    init() {}
}

struct Page1: View {
    u/EnvironmentObject
    private var viewModel: Foo

    u/Binding
    var value: Int

    init() {
        self._value = .init(get: { 0 }, set: { _ in })
    }

    u/State
    private var id: UUID? = nil

    var body: some View {
        NavigationLink(value: 0) {
            Text("Go to page2")
                .padding()
                .foregroundStyle(.white)
                .background(.black)
                .cornerRadius(12)
        }

        .navigationDestination(for: Int.self) { _ in
            Page2(
                onComplete: {
                    print("value", value)
                }
            )
        }
    }
}

struct Page2: View {
    public init(onComplete _: u/escaping () -> Void) {}

    public var body: some View {
        Text("This is Page2")
            .task {
                print("hi")
            }
    }
}
Answered by DTS Engineer in 797166022

@pickyz The code doesn't compile on my end u/EnvironmentObject, u/Binding , u/State isnt a Swift syntax.

Have you created some custom property wrapper here, what OS version and device are you testing on?

Regardless I've rewritten your sample code here and the cpu usage seems normal:


struct ContentView: View {
    @State private var value = 0
    var body: some View {
        NavigationStack {
            Page1(value: $value)
                .environmentObject(Foo())
        }
    }
}

class Foo: ObservableObject {
    init() {}
}

struct Page1: View {
    @EnvironmentObject private var viewModel: Foo
    @Binding var value: Int

    @State
    private var id: UUID? = nil

    var body: some View {
        NavigationLink(value: value) {
            Text("Go to page2")
                .padding()
                .foregroundStyle(.white)
                .background(.black)
                .cornerRadius(12)
        }

        .navigationDestination(for: Int.self) { _ in
            Page2(
                onComplete: {
                    print("value", value)
                }
            )
        }
    }
}

struct Page2: View {
    private var onComplete: () -> Void
    
    init(onComplete: @escaping () -> Void) {
        self.onComplete = onComplete
    }

    public var body: some View {
        Text("This is Page2")
            .task {
                print("hi")
            }
    }
}

@pickyz The code doesn't compile on my end u/EnvironmentObject, u/Binding , u/State isnt a Swift syntax.

Have you created some custom property wrapper here, what OS version and device are you testing on?

Regardless I've rewritten your sample code here and the cpu usage seems normal:


struct ContentView: View {
    @State private var value = 0
    var body: some View {
        NavigationStack {
            Page1(value: $value)
                .environmentObject(Foo())
        }
    }
}

class Foo: ObservableObject {
    init() {}
}

struct Page1: View {
    @EnvironmentObject private var viewModel: Foo
    @Binding var value: Int

    @State
    private var id: UUID? = nil

    var body: some View {
        NavigationLink(value: value) {
            Text("Go to page2")
                .padding()
                .foregroundStyle(.white)
                .background(.black)
                .cornerRadius(12)
        }

        .navigationDestination(for: Int.self) { _ in
            Page2(
                onComplete: {
                    print("value", value)
                }
            )
        }
    }
}

struct Page2: View {
    private var onComplete: () -> Void
    
    init(onComplete: @escaping () -> Void) {
        self.onComplete = onComplete
    }

    public var body: some View {
        Text("This is Page2")
            .task {
                print("hi")
            }
    }
}

Oh the code seem to have broken while copy & paste. Here's the code for 100% reproduction

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            Page1()
                .environmentObject(Foo())
        }
    }
}

class Foo: ObservableObject {
    init() {}
}

struct Page1: View {
    @EnvironmentObject
    private var viewModel: Foo

    @Binding
    var value: Int

    init() {
        self._value = .init(get: { 0 }, set: { _ in })
    }

    @State
    private var id: UUID? = nil

    var body: some View {
        NavigationLink(value: 0) {
            Text("Go to page2")
                .padding()
                .foregroundStyle(.white)
                .background(.black)
                .cornerRadius(12)
        }

        .navigationDestination(for: Int.self) { _ in
            Page2(
                onComplete: {
                    print("value", value)
                }
            )
        }
    }
}

struct Page2: View {
    public init(onComplete _: @escaping() -> Void) {}

    public var body: some View {
        Text("This is Page2")
            .task {
                print("hi")
            }
    }
}

I didn't used any custom property wrapper. I just want to know why this code freezes when navigating to page2.

@DTS Engineer I'm worried that the notification hasn't sent to you. would you please answer again?

Freezing bug in NavigationLink
 
 
Q