带有UIImagView的swift UITableViewController通过HTTP加载其数据

带有UIImagView的swift UITableViewController通过HTTP加载其数据,swift,uitableview,Swift,Uitableview,我正在建立一个歌曲列表。我正在使用UITableViewController,我正在加载JSON,解析它,然后显示它,没有问题。然后,我想通过http为我的单元格加载一个封面图像,实现它没有问题。我的问题是,如果我滚动到底部太快(大约有300首歌曲),我会看到UIImageView循环到它应该加载的所有图像。这是合乎逻辑的,因为它们是重复使用的,我从未停止过加载它们。我的代码如下: override func tableView(tableView:UITableView,cellForRowA

我正在建立一个歌曲列表。我正在使用UITableViewController,我正在加载JSON,解析它,然后显示它,没有问题。然后,我想通过http为我的单元格加载一个封面图像,实现它没有问题。我的问题是,如果我滚动到底部太快(大约有300首歌曲),我会看到UIImageView循环到它应该加载的所有图像。这是合乎逻辑的,因为它们是重复使用的,我从未停止过加载它们。我的代码如下:

override func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
让cell=tableView.dequeueReusableCell(标识符为:“playlitem”,for:indexath)作为!playlitemcell
让歌曲=self.playlayviewmodel!。歌曲[indexPath.row]
cell.artistLabel?.text=song.artist
cell.titleLabel?.text=song.title
让url=url(字符串:https://mydomain.dom/api/songs/images/“+song.id+”/a/6400/”)
cell.coverImage.image=imageCache[url!.absoluteString]
如果cell.coverImage.image==nil{
中的getSongCover(url:url!){(成功,图像)
imageCache[url!.absoluteString]=图像
DispatchQueue.main.async{
cell.coverImage.image=图像
}
}
}
返回单元
}
基本上,我有一个图像缓存:

  var imageCache: [String: UIImage] = [:]

我尝试向UIImageView提供一个来自它的图像,如果它不存在,我下载它,然后将它提供给UIImageView。据我所知,当细胞被重用时,图像在细胞的最后一次“使用”中按顺序加载和显示。但我怎样才能避免呢

不要直接更新单元格,而是使用闭包将图像和单元格的唯一标识符(
song.id
?)传递回viewController上的方法

然后,此方法可以更新缓存,检查具有唯一标识符的单元格是否仍在
tableView.visibleCells
数组中,如果是,则直接使用图像更新它(仍然通过GCD,以便在主线程上获取它)

这将停止显示随机图像,并提高应用程序性能,因为它只会尝试使用可见单元格的图像而不是所有单元格的图像来更新UI


我也会有一个占位符图像显示时,正确的封面不可用(如果你还没有这样做),因为它看起来更一致,特别是当您有por网络访问或后端中断时。

您是否尝试过在您的单元格中实现并清理
封面图像
?在其他部分,请提供一个占位符并指定一个占位符,直到图像加载完毕,它可能会被修复。这是一个很好的基础。请先搜索再提问。@matt,我搜索了,但没有找到解决方案,因此我提出了问题。不过,感谢您的意见。我会尝试一下,这是我第一次听说
tableView.visibleCells
,在尝试将图像放入uiimageview之前,对
tableView.visibleCells
进行测试是否更为实际?@beauchette您正在
tableView(…cellForRowAt…)
只会对可能可见的单元格调用,因此无需检查。问题是,当你快速滚动浏览时,所有单元格都会“可见”几秒钟,因此所有单元格都会发出图像请求。你可以使用滚动事件来做一些更复杂的事情,只请求“真正”可见的图像,但这是一个完全不同的复杂程度。我找到了使它工作的真正方法,因为它似乎不是你在这里谈论的东西,我不会