request.cancel()用于重用的单元格Alamofire swift

时间:2016-05-14 21:42:56

标签: ios swift networking

我有一个带图像的集合视图,我使用Alamofire和AlamofireImage作为网络代码。 在cellForItemAtIndexPath的开头,我将图像设置为nil并使用request?.cancel()取消任何正在进行的请求(如果存在)。 但这样做,一些单元格根本不会填充图像。 你能告诉我我做错了什么吗? 请参阅下面的cellForItemAtIndexPath代码:

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoreCell

    let entry = self.dataCell.addCell[indexPath.section][indexPath.item]

    stringURL = "https://website.com/stories_db/images/\(entry.filename)"

    cell.title.text = entry.title
    cell.subTitle.text = entry.author
    cell.cost.text = entry.cost

    // Reset the cell
    cell.storyImage.image = nil
//  request?.cancel()

    if let image = dataCell.cachedImage(stringURL) {
        cell.storyImage.image = image
    } else {
        request = dataCell.getNetworkImage(stringURL) { image in
            cell.storyImage.image = image
        }
    }

    // Fix the collection view cell in size
    cell.contentView.frame = cell.bounds
    cell.contentView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]

    return cell
}

1 个答案:

答案 0 :(得分:1)

您似乎正在重复使用一个名为var的请求来存储图像请求。如果一次可以看到多个集合视图单元格,则可能需要一次创建多个异步图像请求,因此您需要一种方法来存储多个正在进行的请求。

例如,如果您的集合视图有三个单元格并且所有单元格都可见,那么当它重新加载时,它将调用cellForItemAtIndexPath来获取第一个单元格。您的代码会创建单元格并启动"图像1"的异步请求。并将其存储在您的请求var。

然后集合视图立即再次调用cellForItemAtIndexPath以获取第二个单元格。如果请求"图像1"仍然在进行中,调用请求?.cancel()会中断它所以"图像1"永远不会完成下载。然后代码为"图像2"创建新请求。并将其分配给请求。

集合视图立即调用cellForItemAtIndexPath来获取第三个单元格......

一种解决方案是存储活动请求的数组(或字典)。在您创建请求时添加请求,请求在请求完成时删除(失败或成功)。然后,如果您确定您正在重复使用的单元格正在进行请求,请取消该请求并将其从列表中删除。

另一种方法是创建一个自定义单元子类并让它存储活动请求。这样做的好处是可以更简单地将请求与单元格关联起来。

使用这两种方法,您可能需要考虑在UICollectionViewCell.prepareForReuse()而不是cellForItemAtIndexPath中取消对单元格的活动请求。