【问题标题】:Index out of range for only last 2 values?只有最后 2 个值的索引超出范围?
【发布时间】:2019-03-19 10:37:18
【问题描述】:

我目前的索引超出范围,但这只会在前 3 个项目成功显示后发生。我查看了代码,但我仍然不知道我哪里出错了。仅当尝试在单元格中加载文本时才会发生索引超出范围。

从 viewdidload 调用方法时的日志:

indexPath 说明:0 indexPath 说明:1 indexPath 说明:2

当我按下按钮加载其余图像时记录:

indexPath 说明:0 indexPath 说明:1 indexPath 说明:2 indexPath 说明:3

indexpath 超出范围的数据源方法:

    //MARK: - tableview datasource methods

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    if arrayOfImgObj.count > 0 {
        cell.imageView?.image = arrayOfImgObj[indexPath.row].imageTempt
        print("Description of indexPath: ",indexPath.row)
        cell.textLabel?.text = arrayOfUIDs[indexPath.row] // index out of range
    } else {
        print("\(arrayOfImgObj.count) not over 0 yet")
    }
    return cell
}

viewDidload 时调用的方法:

    //testing array
var arrayOfUIDs = User().users

func fetchAllUserFristImage() {
    Database.database().reference().child("Posts").observe(.childAdded, with: {(snapshot) in

        if (snapshot.value as? [String: AnyObject]) != nil {
            let user = User()

            user.id = snapshot.key

            //testing array
            self.arrayOfUIDs.append(snapshot.key)

            print("\(String(describing: user.id)) <-- SHUD BE THE USERUID")

            self.databaseRef = Database.database().reference()

            let usersPostRef2 = self.databaseRef.child("Posts").child(user.id!)

            usersPostRef2.observe(.value, with: {(postXSnapshots) in

                if let postDictionary2 = postXSnapshots.value as? NSDictionary {

                    for (p) in postDictionary2 {

                        let posts = p.value as! NSDictionary

                        //to get back to where i was delete the below for i
                        for (i) in posts {

                            let imageUrlString = i.value as! NSDictionary

                            guard let postUrl = imageUrlString.value(forKey: "image1") else {return}

                            //below is ting from below
                            if postUrl != nil {

                                self.feedArray.append(Post(fetchedImageURL: postUrl as! String))

                                let imageUrlString = "\(postUrl)"

                                let imageUrl = URL(string: imageUrlString)!
                                print("\(imageUrl) this shud be img url's of posts")

                                let imageDataL = try! Data(contentsOf: imageUrl)
                                self.imageObject.img2 = UIImage(data: imageDataL)
                                let image1ToDisplay: UIImage = self.imageObject.img2!
                                self.arrayOfImgObj.append(forTable(imageTempt: image1ToDisplay))

                            } else {print("this user had no posts, was nil")}
                        }
                    }
                }
            })
        }
        //below shud stay same
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    })
}

编辑:

我已将代码更改为仅使用一个对象数组:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    if arrayOfImgObj.count > 0 {
        cell.imageView?.image = arrayOfImgObj[indexPath.row].imageTempt
        print("Description of indexPath: ",indexPath.row)
        cell.textLabel?.text = arrayOfImgObj[indexPath.row].users[indexPath.row] // index out of range
    } else {
        print("\(arrayOfImgObj.count) not over 0 yet")
    }

    return cell
}

将函数中的一行改为:

self.arrayOfImgObj.append(forTable(imageTempt: image1ToDisplay, users: snapshot.key))

提前致谢!

【问题讨论】:

  • 在网络调用完成后重新加载表。
  • 显示您的 numerOfRows 代码 - 此函数应返回数组的 count。您返回的计数必须多于数组中的元素数。
  • 我只返回arrayOfImgObj.count @Paulw11
  • 另外,如果可以避免的话,你不应该在 Swift 中使用NSDictionary
  • 是的,您应该使用适当的字典类型,可能是[String:Any]。为什么说不重新开始?绝对推荐使用 Swift 类型。

标签: ios arrays swift firebase firebase-realtime-database


【解决方案1】:

你的问题是你有两个数组:

  • arrayOfUIDs 每个用户都有一个条目
  • arrayOfImgObj,每个用户有 0-n 个条目(因此,该数组中的对象数很可能大于 arrayOfUIDs 中的对象数。

您的行数基于arrayOfImgObj,但随后使用行号索引arrayOfUIDs,这会导致数组边界异常。

为每个用户 ID 设置表格视图部分可能会更优雅,但如果您想将所有行放在一个部分中,我建议您使用单个结构数组作为数据模型。

使用类似的东西:

struct UserImage {
    var userID: String
    var image: UIImage
}


var tableData = [UserImage]()

然后,当您获取每个图像时,创建一个新结构并将其放入您的数组中:

func fetchAllUserFristImage() {
    Database.database().reference().child("Posts").observe(.childAdded, with: {(snapshot) in

        if snapshot.value as? [String: AnyObject] != nil {
            let user = snapshot.key

            self.databaseRef = Database.database().reference()

            let usersPostRef2 = self.databaseRef.child("Posts").child(user)

            usersPostRef2.observe(.value, with: {(postXSnapshots) in

                if let postDictionary2 = postXSnapshots.value as? [String:AnyObject] {

                    for (p) in postDictionary2 {

                        if let posts = p.value as? [String:AnyObject] {

                            //to get back to where i was delete the below for i
                            for (i) in posts {

                                if let imageUrlString = i.value as? [String:AnyObject], let postUrl = imageUrlString.["image1"] as? String {

                                    self.feedArray.append(Post(fetchedImageURL: postUrl))
                                    if let imageUrl = URL(string: postUrl), let imageDataL = try? Data(contentsOf: imageUrl), let image = UIImage(data: imageDataL) {

                                        self.tableData.append(UserImage(userID: user, image: image))
                                    } else {print("this user had no posts, was nil")}
                                }
                            }
                        }
                    }
                }
            })
                //below shud stay same
                DispatchQueue.main.async {
                    self.tableView.reloadData()
            }
        }
    })

}

现在,您的cellForRow 可以是:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    cell.imageView?.image = tableData[indexPath.row].image
    cell.textLabel?.text = tableData[indexPath.row].userID

    return cell
}

【讨论】:

  • 不要删除你的答案我会在大约一个小时内测试它
  • 它似乎运行正常,但它没有在表格视图中显示图像:我尝试在表格视图方法中打印一些东西,但从未调用过该打印语句
  • 添加char@Paulw11
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 2022-01-13
  • 2020-11-05
相关资源
最近更新 更多