gpt4 book ai didi

swiftui - NavigationLink 在 NavigationStack 中触发多次

转载 作者:行者123 更新时间:2023-12-05 05:32:34 42 4
gpt4 key购买 nike

NavTestChildView 多次调用时,我遇到了这个问题。我不明白出了什么问题。我在装有 iOS 16.0.3 和模拟器 Xcode 14.0.1 的真实设备上进行了测试

我替换了原始代码以提供更多关于我将 NavTestService 创建到 navigationDestination 的架构的信息。

enum NavTestRoute: Hashable {
case child(Int)
}

class NavTestService: ObservableObject {
let num: Int

init(num: Int) {
self.num = num
print("[init][NavTestService]")
}

deinit {
print("[deinit][NavTestService]")
}
}

struct NavTestChildView: View {
@EnvironmentObject var service: NavTestService

init() {
print("[init][NavTestChildView]")
}

var body: some View {
Text("NavTestChildView \(service.num)")
}
}

struct NavTestMainView2: View {
var body: some View {
VStack {
ForEach(1..<10, id: \.self) { num in
NavigationLink(value: NavTestRoute.child(num)) {
Text("Open child \(num)")
}
}
}
}
}

struct NavTestMainView: View {
var body: some View {
NavigationStack {
NavTestMainView2()
.navigationDestination(for: NavTestRoute.self) { route in
switch route {
case let .child(num):
NavTestChildView().environmentObject(NavTestService(num: num))
}
}
}
}
}

日志:

[init][NavTestChildView]
[init][NavTestService]
[deinit][NavTestService]
[init][NavTestChildView]
[init][NavTestService]

最佳答案

看起来有一段时间 NavTestService 的实例没有被任何人持有并且它离开了堆。实际上,这几乎不会发生,因为 .environmentObject 变量通常位于层次结构的某个位置。如果相应地更改 NavTestMainView:

struct NavTestMainView: View {
let navTestService = NavTestService()
var body: some View {
NavigationStack {
NavigationLink(value: NavTestRoute.child) {
Text("Open child")
}
.navigationDestination(for: NavTestRoute.self) { route in
switch route {
case .child:
NavTestChildView().environmentObject(navTestService)
}
}
}
}
}

...您没有deinit,也没有额外的init。控制台会输出:

[init()][NavTestService]
[init()][NavTestChildView]
[init()][NavTestChildView]

另请注意,如果您注释掉 let navTestService = NavTestService() 并将 NavTestChildView().environmentObject(NavTestService()) 包裹在 LazyView 中,您将获得以下内容输出:

[init()][NavTestChildView]
[init()][NavTestService]

LazyView 是:

struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}

关于swiftui - NavigationLink 在 NavigationStack 中触发多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74056543/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com