在SwiftUI中访问数组中的元素时出现“致命错误:索引超出范围”

问题描述

在swiftUI中,我试图创建一个包含乘法表中项目的数组。 (1 x 1 = 1,1 x 2 = 2,依此类推),并将其中一些显示用户

所以我首先创建了一个Struct

struct TableItem {

        var serialNumber: Int

        var numberA: Int
        var numberB: Int

        var result: Int {
           return numberA * numberB
        }

        init(giveNumberA:Int,giveNumberB:Int,giveSerialNumber: Int) {
            self.numberA = giveNumberA
            self.numberB = giveNumberB
            self.serialNumber = giveSerialNumber
    }
 }

然后在ContentView中创建了Initialization函数,并在View中尝试显示数组中的随机项:

struct ContentView: View {

@State private var allTableItems = [TableItem]()

@State private var currentDebug = Int.random(in: 0...10)

let tableupperLimit = 13


var body: some View {
    
    NavigationView{
        vstack{
            Text("\(allTableItems[currentDebug].numberA) * \(allTableItems[currentDebug].numberB) = ?")
                .padding()
                .font(.title)
            
            Text("some other texts")
        }
        .navigationBarTitle("edutainment")
        .onAppear(perform: InitializeTheTable)
        .navigationBarItems(trailing:
                            Button(action: InitializeTheTable) {
                                Text("Reset")
                                }
                        )
    }

    

}


func InitializeTheTable() {
    //Step 1: initialize the full table
    var initCounter = 0
    
    for i in 1 ..< tableupperLimit {
        for j in i ..< tableupperLimit {
            
            let tempItem  = TableItem(giveNumberA: i,giveNumberB: j,giveSerialNumber: initCounter)
            
            allTableItems.insert(tempItem,at: initCounter)
            
            //This is for debug purpose
            print("\(initCounter):  \(allTableItems[initCounter].numberA) * \(allTableItems[initCounter].numberB) = \(allTableItems[initCounter].result) \n")
            
            initCounter+=1
        }
    }
}

在此视图加载时,它会调用InitializeTheTable(),在此设计中,使用两个for循环将itsm插入到数组中,从“ 1 1”开始,到“ 12 12”结束。

从控制台日志中,我可以看到大约有70多个项目按预期插入了数组“ allTableItems”。

但是,在vstack中,当我尝试从arry中提取一个随机项(index:currentDebug)并显示为文本时,出现了“致命错误:索引超出范围”。

代码可以构建,但是会崩溃并且无法运行。想知道为什么数组出现“超出范围”错误?谢谢

解决方法

Text函数之前初始化VStack中的.onAppear (perform: InitializeTheTable)属性时,会发生此问题。 我想出了一个解决这个问题的主意 在赚钱之前,您需要在Struct ContentView中创建2个变量:

@State private var numberA = 0 // <--- here
@State private var numberB = 0 // <--- here

然后在循环结束时在InitializeTheTable函数中执行以下操作:

numberA = allTableItems[currentDebug].numberA
numberB = allTableItems[currentDebug].numberB

要使用@State为numberA和numberB分配值,这两个变量将在界面上刷新

func InitializeTheTable() {
    //Step 1: initialize the full table
    var initCounter = 0
    
    for i in 1 ..< tableUpperLimit {
        for j in i ..< tableUpperLimit {
            
            let tempItem  = TableItem(giveNumberA: i,giveNumberB: j,giveSerialNumber: initCounter)
            
            allTableItems.insert(tempItem,at: initCounter)
            
            //This is for debug purpose
            print("\(initCounter):  \(allTableItems[initCounter].numberA) * \ 
(allTableItems[initCounter].numberB) = \(allTableItems[initCounter].result) \n")
            
            initCounter+=1
        }
    }
    
    numberA = allTableItems[currentDebug].numberA // <--- here
    numberB = allTableItems[currentDebug].numberB // <--- here
}

请更新代码

Text("\(allTableItems[currentDebug].numberA) * \(allTableItems[currentDebug].numberB) = ?")
            .padding()
            .font(.title) // <-- Old
Text("\(numberA) * \(numberB) = ?")
            .padding()
            .font(.title) // <-- New