致命错误:索引超出范围 - Swift 3 和 Firebase

Posted

技术标签:

【中文标题】致命错误:索引超出范围 - Swift 3 和 Firebase【英文标题】:Fatal error: index out of range - Swift 3 and Firebase 【发布时间】:2016-12-21 19:49:48 【问题描述】:

我有 Swift 3 和 Firebase 的基本经验,我正在为我所在城市的一群朋友开发一个应用程序,他们是当地一所学校的老师。他们想要一个应用程序,以一种与他们联系的方式验证他们的学生的清单。

我有一个带有第一个视图控制器和表格视图的应用程序,然后单击添加学生我有一个带有另外三个视图控制器的标签栏控制器。在第一个错误来自的地方,我有 2 个选择器视图:1) 学生 (pckStudents) 和 2) 教师 (pckTeachers)。它们来自 Firebase 中同一主根的不同节点(子节点)。

Main root –
    -- Validation2017
          -- teachers
              -- key
              -- teacherName
          -- students
              -- key
              -- studentName
          -- validation
              -- key
              -- name
              -- final note
              -- dateTime
              ---- Level 1 (...)

在这两个选择器视图所在的第一个视图控制器中,我有数组的声明:

var teachers: [teachers] = []
var students: [students] = []

我必须创建两个不同的数组,一个用于学生,一个用于教师。首先,因为它们是不同种类的数据,它们之间没有关系;其次,因为我尝试过的所有其他方法都无法解决尝试加载数据的问题,而这两个项目只有一个观察值;每个孩子一张快照。

这样做,视图控制器加载正常,但总是当我单击以选择选择器视图之一时,我收到消息:致命错误:索引超出范围。有时当我单击选择器视图 1 时出现此错误,有时是数字 2。我也不知道为什么会这样。

我已经尝试了在这里和其他网站上找到的所有描述和解决方案,但我无法修复它,也没有找到专门针对 Swift 3 和 Xcode 8 的描述和解决方案,我希望有人可以帮助我。对不起我的英语(我正在努力做到最好),如果我以错误的方式编写了一些术语或函数或一些代码操作。感谢您的关注。

我的两个数组的子类:(只切换学生...为老师...)

struct students 

var studentName: String?
var key: String!

init(studentName: String, key: String = "") 
    self.studentName = studentName
    self.key = key


init(snapshot: FIRDataSnapshot) 
    key = snapshot.key
    let snapshotValue = snapshot.value as! [String: AnyObject]
    studentName = snapshotValue["studentName"] as? String


func toAnyObject() -> Any 
    return [
        "studentName": studentName,
        "userKey": key
    ]

然后,我创建了两种方法 - CarregarT() 和 CarregarS() - 用于加载每个数组(放置在 viewDidLoad):(为“students”切换“teaches”和“teacherName”,为 CarregarA() 切换“studentName”)

func CarregarT() 
    let refW = FIRDatabase.database().reference().child("Validation2017").child("teachers")
    refW.queryOrdered(byChild: "teacherName").observe(.value, with: (snapshot) in

        var newTeste2: [teachers] = []
        for resposta in snapshot.children 
            let itemsAadicionar = teachers(snapshot: resposta as! FIRDataSnapshot)
            newTeste2.append(itemsAadicionar)
        
        self.refw2 = newTeste2
        self.pckTeachers.reloadAllComponents()
      )

最后,用于 1 和 2 的 UIPickerView 方法(我将 pickerview 1 签名为 tag=1 并将 pcv2 签名为 tag=2)

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
    if pickerView.tag == 1 
        return teachers.count
     else
        return students.count


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
    if pickerView.tag == 1 
    return teachers[row].teacherName
else
return students[row].studentName
     

谢谢。

更新:方法 didSelectRow

var PreceptorG: String!
var NomeG: String!

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 

        let studentCh = students[row].studentName
        let teacherCh = teachers[row].teacherName

            if pickerView.tag == 1
              PreceptorG = teacherCh

            else
                NomeG = studentCh
              
        

对不起,我之前忘记了这个方法。

【问题讨论】:

我很困惑哪一行会产生错误。你会指出来吗?是从这里来的吗teachers[row] 添加 numberOfComponentsInPickerView 并返回 1,假设您有一个组件?此外,这不是技术问题,但您的学生和教师结构称为teacherArray,您可能需要调用studentStruct 和teacherStruct 以清楚起见。 对不起,对不起@Honey。我忘记了 didSelectRow。该方法会显示错误消息。抱歉,我已经更新了上面的代码。 @Jay,我已经完成了numberOfComponentsInPickerViewreturn 1。只是没有放在这里,因为文字有点长。 在你的didSelectRow 的第一行做print(students) 可能你的数组是空的并且你正在访问一个不存在的索引 【参考方案1】:

在 didSelecRow 内部,我将行 let studentCh = students[row].studentName 移动到其 pickerview.tag 引用中,并且与另一行相同。这是 didSelectRow 的最终代码。现在不再崩溃:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 

            if pickerView.tag == 1
            let teacherCh = teachers[row].teacherName
            PreceptorG = teacherCh

            else
            let studentCh = students[row].studentName
            NomeG = studentCh

  
        

【讨论】:

以上是关于致命错误:索引超出范围 - Swift 3 和 Firebase的主要内容,如果未能解决你的问题,请参考以下文章

Swift 致命错误:数组索引超出范围

Swift TableView ImageView + Label = 致命错误:索引超出范围

致命错误:索引超出范围:Swift

(Swift) 致命错误:索引超出范围

Xcode Swift:致命错误:索引超出范围

Swift CollectionView(致命错误:索引超出范围)