数组元素的SwiftUI NavigationLink@绑定导致致命错误:索引超出范围

数组元素的SwiftUI NavigationLink@绑定导致致命错误:索引超出范围,swift,swiftui-navigationlink,swiftui,environmentobject,Swift,Swiftui Navigationlink,Swiftui,Environmentobject,我有一个可观察的物体,这是我唯一的真理来源: class NetworkFetcher: ObservableObject { @Published var list: [Car] = [Car(id: UUID().uuidString, name: "Tesla"), Car(id: UUID().uuidString, name: "BMW")] func erase() { DispatchQueue.main.a

我有一个可观察的物体,这是我唯一的真理来源:

class NetworkFetcher: ObservableObject {
    @Published var list: [Car] = [Car(id: UUID().uuidString, name: "Tesla"), Car(id: UUID().uuidString, name: "BMW")]

    func erase() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0) {
            self.list = []
        }
    }

    func add() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0) {
            self.list = [Car(id: UUID().uuidString, name: "Tesla S"), Car(id: UUID().uuidString, name: "BMW M3")]
        }
    }
}
这是车:

struct Car: Identifiable, Hashable {
    var id: String
    var name: String
}
在这里,擦除和添加(编辑列表的功能)工作正常:

struct ContentView: View {
    @ObservedObject var net: NetworkFetcher = NetworkFetcher()

    var body: some View {
        NavigationView {
            VStack {
                ListView(liste: self.$net.list, net: self.net)
                Button(action: {
                    self.net.erase()
                }) {
                    Text("erase")
                }
                Button(action: {
                    self.net.add()
                }) {
                    Text("add")
                }
            }
        }
    }
}

struct ListView: View {
    @Binding var liste: [Car]
    @ObservedObject var net: NetworkFetcher

    var body: some View {
        List {
            ForEach(liste.indices, id: \.self) { i in
                NavigationLink(destination: CarView(c: self.$liste[i], net: self.net)) {
                    Text(self.liste[i].name)
                }
            }
        }
    }
}
问题在于:

struct CarView: View {
    @Binding var c: Car
    @ObservedObject var net: NetworkFetcher

    var body: some View {
        VStack {
            TextField("car name :", text: $c.name)
            Button(action: {
                self.net.erase()
            }) {
                Text("erase")
            }
            Button(action: {
                self.net.add()
            }) {
                Text("add")
            }
        }
    }
}
如果单击“擦除”按钮,主列表将变为空数组。但是应用程序崩溃了,我得到了这个错误:

致命错误:索引超出范围:file/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift,第444行

问题是:

  • 为什么?
  • 如何解决

  • 你真的

    哇!另一个问题的答案适用于这里。见:

    因此,您应该使用以下方法更改ListView:

    struct ListView: View {
        @Binding var liste: [Car]
        @ObservedObject var net: NetworkFetcher
    
        var body: some View {
            List {
                ForEach(liste.indices, id: \.self) { i in
                    NavigationLink(destination: self.row(for: i)) {
                        Text(self.liste[i].name)
                    }
                }
            }
        }
    
        private func row(for idx: Int) -> some View {
            let isOn = Binding(
                get: {
                    // safe getter with bounds validation
                idx < self.liste.count ? self.liste[idx] : Car(id: UUID().uuidString, name: "EMPTY")
            },
                set: { self.liste[idx] = $0 }
            )
            return CarView(c: isOn, net: self.net)
        }
    }
    
    结构列表视图:视图{ @绑定变量列表:[Car] @ObservedObject变量网络:NetworkFetcher var body:一些观点{ 名单{ ForEach(liste.index,id:\.self){i in 导航链接(目的地:self.row(for:i)){ 文本(self.liste[i].name) } } } } 私有func行(对于idx:Int)->某些视图{ 让我来看看( 获取:{ //带边界验证的安全getter idx如果您找到另一个以完全相同的方式解决问题的方法,您可以将其标记为重复。