我有一个表格视图,我想用Firebase数据填充,还有一个存储在存储中的图像。
我最初的游戏计划是运行一个观察者到 firebase,对于快照中的每个项目,填充一个 firebase 数据数组,并使用相同的快照名称从存储中提取数据,并将其放入另一个两者都匹配的数组中,然后在我的单元格中,我会用图像数组的 indexpath.row 填充图像, 和来自数据数组的数据,它会匹配并且很酷。
这次崩溃和烧毁是因为从存储下载图像我想比提取信息花费更长的时间? 并且图像数组的填充速度比数据慢,因此我遇到图像[indexPath.row]超出范围的崩溃。
使用来自数据库和存储的数据填充表视图的正确方法是什么?
编辑:
我的火力基础数据如下所示:
users
02938409283049829304
Category
Cats : true
Dogs: true
这就是我试图做的:
REF_USERS.child(currentUserUID).child("Category").observeEventType(.Value) { ( snapshot: FIRDataSnapshot) in
self.categoriesArray = []
self.imagesArray = []
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
self.categoryArray.append(snap.key)
let pictureRef = DataService.ds.REF_BASE_STORAGE.child(self.currentUserUID).child(String(snap.key))
pictureRef.dataWithMaxSize(9809898999098098 /* no idea what to put here*/) { (data, error) -> Void in
if (error != nil) {
print(error)
} else {
let picture : UIImage! = UIImage(data: data!)
self.imagesArray.append(picture)
print(self.imagesArray.count)
}
}
self.tableView.reloadData()
所以我想读的是:
转到用户并查看其类别。我想发布它的名称,所以我只使用密钥。密钥名称与保存到存储中的图像完全相同,因此我使用该密钥名称从存储中获取照片。
let pictureRef = DataService.ds.REF_BASE_STORAGE.child(self.currentUserUID).child(String(snap.key))
我将数据库中的数据添加到一个数组中,将存储中的图像添加到另一个数组中,然后在制作单元格时,我只需将数据设置为 data[indexPath.row] 并将图像设置为 images[indexPath.row]。当我做 images.count 和 data.count 并且我在这两件事中都有 3 件事时,我的图像落后了 3 个滞后,所以这就是我猜我得到的图像 [indexPath.row] 超出范围错误的地方。
我通常异步加载图像,我有一个委托方法,该方法在下载完成时触发,并在下载新数据/图像时刷新表视图。
制作占位符图像并可能带有旋转加载器图标将在下载图像之前显示会很棒。
编辑:
您需要在 pictureRef.dataWithMaxSize 方法中调用 self.tableview.reload()。由于下载是异步的,因此您的表视图现在将在方法 REF_USERS.child 完成时重新加载,而不一定在下载图像时重新加载。因此,要么将self.tableview.reloadData放在pictureRef.dataWithMaxSize中的else中,要么在同一位置创建一个委托方法来处理完成的下载图像。
我觉得最好的方法是显示占位符图像,或者为您从数据库中调用的每个图像显示加载图标。当图像传入时,您可以相应地更新表视图。
执行此操作的另一种方法是异步运行请求,一旦所有进程完成,即可一起显示所有图像。
您甚至可以显示加载屏幕,并在显示 tableView 之前加载图像。
您所要做的就是在开始将图像添加到 tableView 之前确保图像存在,并确保内存使用量不会过高。