【发布时间】:2020-06-09 18:30:29
【问题描述】:
我正在使用 Firebase 在我的 iOS 应用程序中填充 TableView。前几个对象已加载,但一旦我到达列表中的第三个项目,应用程序就会崩溃并出现异常:
'NSRangeException', reason: '*** __boundsFail: index 3 beyond bounds [0 .. 2]'
我知道这意味着我指的是一个不包含索引的数组,但我不知道为什么。
我用TableViewController 创建TableView 并像这样初始化它:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(posts.count)
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let post = posts[indexPath.row]
print(post)
let cell = tableView.dequeueReusableCell(withIdentifier: K.cellIdentifier, for: indexPath) as! PostCell
let firstReference = storageRef.child(post.firstImageUrl)
let secondReference = storageRef.child(post.secondImageUrl)
cell.firstTitle.setTitle(post.firstTitle, for: .normal)
cell.secondTitle.setTitle(post.secondTitle, for: .normal)
cell.firstImageView.sd_setImage(with: firstReference)
cell.secondImageView.sd_setImage(with: secondReference)
// Configure the cell...
return cell
}
我相信第一个函数创建了一个数组,其中包含 posts 中的对象数,并且第二个函数将值分配给单元格的模板。第一种方法中的 print 语句打印 4,这是从 firebase 检索到的正确数量的对象。我假设这意味着创建了一个数组,其中包含要在TableView 中显示的 4 个对象。这是真正令人困惑的地方,因为错误表明数组中只有 3 个对象。我是否误解了TableView 的实例化方式?
这是填写TableView的代码:
func loadMessages(){
db.collectionGroup("userPosts")
.addSnapshotListener { (querySnapshot, error) in
self.posts = []
if let e = error{
print("An error occured trying to get documents. \(e)")
}else{
if let snapshotDocuments = querySnapshot?.documents{
for doc in snapshotDocuments{
let data = doc.data()
if let firstImage = data[K.FStore.firstImageField] as? String,
let firstTitle = data[K.FStore.firstTitleField] as? String,
let secondImage = data[K.FStore.secondImageField] as? String,
let secondTitle = data[K.FStore.secondTitleField] as? String{
let post = Post(firstImageUrl: firstImage, secondImageUrl: secondImage, firstTitle: firstTitle, secondTitle: secondTitle)
self.posts.insert(post, at: 0)
print("Posts: ")
print(self.posts.capacity)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
}
应用程序构建并运行并显示前几个项目,但在我滚动到列表底部时崩溃。非常感谢任何帮助。
编辑:
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.register(UINib(nibName: K.cellNibName, bundle: nil), forCellReuseIdentifier: K.cellIdentifier)
loadMessages()
}
【问题讨论】:
-
代码中没有证据表明出现越界崩溃。它不相关,但将
self.tableView.reloadData()替换为self.tableView.insertRows(at: [0,0], with: .automatic)以获得动画插入或将DispatchQueue块移动到循环之后。 -
@vadian,谢谢您的评论是否有可能我可以添加的代码会有所帮助?我认为这是
TableView创建的,所以这将是问题的根源 -
还可以考虑在后台队列中解析数据。 Firestore 在主线程上返回。
-
@bsod 我不熟悉如何做到这一点,你能指出一个可以帮助我的资源吗?我将非常感激。非常感谢您的所有帮助。
-
编辑了我的答案以包括后台排队。首先阅读:stackoverflow.com/questions/19179358/…
标签: ios swift firebase tableview