UICollectionViewCell 重用异步图像加载错误的图像

UICollectionViewCell Reuse with Asynchronous Image Loading wrong image

我正在创建一个 UICollectionView,它最初从 AWSS3 存储桶下载图像,然后缓存图像供以后访问。问题在于,由于下载需要一些时间,因此当用户滚动 UICollectionView 时,会有更多的下载排队。第一批下载完成并加载到新可见的单元格中,然后第二批下载完成并替换相同的单元格。

这会导致图像出现在它们不应该出现的单元格中。我尝试过类似帖子的解决方案,但没有找到一个有效的方法。

这是我尝试过的简化版本

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    var cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("imageCell", forIndexPath: indexPath) as! GroupImageCell

    cell.imageView.image = nil

    getPhotoForCell(cell, indexPath)
}

func getPhotoForCell(cell: GroupImageCell, idx: NSIndexPath)
{
    #use AWSS3downloadrequest
    #once results are in
    if (task.result != nil) {
        #get body of result, then url, then data
        let data = NSData(data: task.result.body as! NSURL)

        let image = UIImage(data: data)
        if (collectionView.cellForItemAtIndexPath(idx) != nil)
        {
            dispatch_async(dispatch_get_main_queue(), {
                cell.imageView.image = image
            })
        } 
    }
}

您可以通过将图像存储在用于每个单元格的模型对象中来解决此问题。意思是,而不是

dispatch_async(dispatch_get_main_queue(), {
                cell.imageView.image = image
            })

做这样的事情

dispatch_async(dispatch_get_main_queue(), {
                items[indexPath.row].image = image
            })

这样,当您从 cellForItemAtIndexPath 方法调用时,您将保证呈现正确的图像。

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    var cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("imageCell", forIndexPath: indexPath) as! GroupImageCell

    cell.imageView.image = items[indexPath.row].image
}