我有一个tableview我想要填充firebase数据以及我存储在存储中的图像。
我最初的游戏计划是为firebase运行一个观察者,并为快照中的每个项目填充一个firebase数据数组,并使用相同的快照名称从存储中提取数据并将其放入另一个匹配的数组中,然后在我的单元格中,我用图像数组的indexpath.row和数据数组中的数据填充图像,它匹配起来很酷。
这次崩溃和烧毁是因为从存储中下载图片我认为花费的时间比拉信息要长吗?并且图像数组的填充速度比数据慢,所以我得到的图像[indexPath.row]超出了范围。
使用数据库和存储中的数据填充tableview的正确方法是什么?
编辑:
我的firebase数据如下:
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))
我将数据库中的数据添加到数组中,将数据从存储添加到另一个数组,然后当我创建单元格时,我只需将数据设置为数据[indexPath.row],将图像设置为图像[indexPath.row ]。当我做images.count和data.count时,我有两件事情,我的图像落后3落后,这就是我猜图像[indexPath.row]超出范围误差的地方。
答案 0 :(得分:1)
我觉得你能做到这一点的最好方法是显示占位符图像,或者从数据库调用的每个图像的加载图标。随着图像进入,您相应地更新tableView。
另一种方法是异步运行请求,并且只要所有进程完成,就会一起显示所有图像。
您甚至可以在显示tableView之前显示加载屏幕并加载图像。
您需要做的就是在开始将图像添加到tableView之前确保图像存在,并确保内存使用不会过分。
答案 1 :(得分:1)
我通常以异步方式加载图像,并且我有一个委托方法,在下载完成时触发,并在下载新数据/图像时刷新tableview。
在下载图像之前,制作占位符图像并使用旋转加载器图标可以很好地显示。
编辑:
您需要在pictureRef.dataWithMaxSize方法中调用self.tableview.reload()。 由于下载是异步的,因此当方法REF_USERS.child完成时,您的tableview将重新加载,而不一定在下载图像时重新加载。 因此,要么将self.tableview.reloadData放在pictureRef.dataWithMaxSize中的else claus中,要么在同一个地方创建一个委托方法来处理已完成的下载图像。