致命错误:在特定视图上刷新数据时,索引超出范围

时间:2020-07-30 12:24:08

标签: swiftui swiftui-list

我有以下代码:

import SwiftUI
import SwiftUIRefresh // added via SwiftPM: https://github.com/timbersoftware/SwiftUIRefresh.git

struct AView: View {
    
    @State private var aObjects = [A]()
    @State private var refreshing = false
    
    var body: some View {
        NavigationView {
            VStack {
                if(aObjects.isEmpty) {
                    Text("loading")
                } else {
                    List(aObjects.indices, id: \.self) { idx in
                        NavigationLink(destination: BView(parentA: self.$aObjects[idx])) {
                            Text(self.aObjects[idx].name)
                        }
                    }.pullToRefresh(isShowing: self.$refreshing) {
                        API.getAs() { newAObjects in
                            self.aObjects = newAObjects
                            self.refreshing = false
                        }
                    }
                }
            }.navigationBarTitle("All", displayMode: .large)
            
        }.onAppear() {
            if(self.aObjects.isEmpty) {
                API.getAs() { newAObjects in
                    self.aObjects = newAObjects
                }
            }
        }
    }
}

struct BView: View {
    
    @Binding var parentA : A
    
    @State private var refreshing = false
    
    var body: some View {
        VStack {
            if(parentA.bs.isEmpty) {
                Text("loading")
            } else {
                List(parentA.bs.indices, id: \.self) { idx in
                    NavigationLink(destination: CView(parentA: self.$parentA, parentB: self.$parentA.bs[idx])) {
                        Text(self.parentA.bs[idx].name)
                    }
                }.pullToRefresh(isShowing: self.$refreshing) {
                    API.getBs(forA: self.parentA) { newBObjects in
                        self.parentA.bs = newBObjects
                        self.refreshing = false
                    }
                }
            }
        }
        .navigationBarTitle(Text(parentA.name), displayMode: .inline)
        .onAppear() {
            if(self.parentA.bs.isEmpty) {
                API.getBs(forA: self.parentA) { newBObjects in
                    self.parentA.bs = newBObjects
                }
            }
        }
    }
}

struct CView: View {
    
    @Binding var parentA : A
    @Binding var parentB : B
    
    @State private var refreshing = false
    
    var body: some View {
            VStack {
                if(parentB.cs.isEmpty) {
                    Text("loading")
                } else {
                    List(parentB.cs.indices, id: \.self) { idx in
                        Text(self.parentB.cs[idx].name + self.parentB.cs[idx].description)
                    }.pullToRefresh(isShowing: self.$refreshing) {
                        API.getCs(forB: self.parentB, inA: self.parentA) { newCObjects in
                            self.parentB.cs = newCObjects
                            self.refreshing = false
                        }
                    }
                }
            }
            .navigationBarTitle(Text(parentB.name), displayMode: .inline)
            .onAppear() {
                if(self.parentB.cs.isEmpty) {
                    API.getCs(forB: self.parentB, inA: self.parentA) { newCObjects in
                        self.parentB.cs = newCObjects
                    }
                }
            }
    }
}


class API {
    
    static func getAs(complete : @escaping ([A]) -> Void) {
        // normaly download from server
        let aobjects = [A(id: 1, name: "1"), A(id: 2, name: "2"), A(id: 3, name: "3")]
        complete(aobjects)
    }
    
    static func getBs(forA : A, complete: @escaping ([B]) -> Void) {
        // normaly download all bs for a provided A from server
        let bObjects = [B(id: 4, name: "4"), B(id: 5, name: "5")]
        complete(bObjects)
    }
    
    static func getCs(forB : B, inA: A, complete: @escaping ([C]) -> Void) {
        // normaly download all cs for a provided B in parent A from server
        let cObjects = [C(id: 6, name: "name", description: "desc")]
        complete(cObjects)
    }
}

struct A {
    public let id : Int
    public let name : String
    public var bs = [B]()
    
    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

struct B {
    public let id : Int
    public let name : String
    public var cs = [C]()
    
    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

struct C {
    public let id : Int
    public let name : String
    public let description : String
    
    init(id: Int, name: String, description : String) {
        self.id = id
        self.name = name
        self.description = description
    }
}

到目前为止,该方法有效。用户可以从AView导航到BView,再导航到CView。如果用户执行以下操作,则会出现标题上的问题和错误:从AView开始,转到BView,转到CView,回到BView,回到AView,通过下拉手势刷新。在其他情况下,它不会发生,例如。从AView开始,转到BView,转到CView,再回到BView,再回到AView,转到另一个BView,再回到AView ,通过下拉手势刷新即可。知道如何防止异常吗?

预先感谢

编辑:完整的错误消息

致命错误:索引超出范围:文件/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift,第444行 2020-07-30 14:16:37.652919 + 0200 TestForArray [11908:625819]致命错误:索引超出范围:文件/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/ stdlib / public / core / ContiguousArrayBuffer.swift,第444行

0 个答案:

没有答案