简体   繁体   English

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

[英]request.cancel() for reused cell Alamofire swift

I have a collection view with images, I am using Alamofire and AlamofireImage for the networking code. 我有一个带有图像的集合视图,我正在使用Alamofire和AlamofireImage作为网络代码。 At the beginning of the cellForItemAtIndexPath I set the image to nil and cancel any in-flight request if one exists, using request?.cancel(). 在cellForItemAtIndexPath的开头,我将图像设置为nil,并使用request?.cancel()取消任何正在进行的请求(如果存在)。 But doing so, some cells won't be populated with images at all. 但是这样做的话,有些单元格根本不会填充图像。 Can you show me what I am doing wrong? 你能告诉我我做错了什么吗? See my cellForItemAtIndexPath code below: 请参阅下面的我的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
}

It looks like you're reusing a single var called request to store the image request. 看起来您正在重复使用一个名为request的变量来存储图像请求。 If more than one of your collection view cells is visible at a time, you may need to make more that one async image request at a time, so you need a way to store multiple in-progress requests. 如果一次可以看到多个集合视图单元,则可能需要一次发出一个以上的异步图像请求,因此需要一种存储多个正在进行的请求的方法。

For example, if your collection view has three cells and all are visible, when it reloads it will call cellForItemAtIndexPath to get the first cell. 例如,如果您的集合视图有三个单元格,并且所有单元格都是可见的,则在重新加载时,它将调用cellForItemAtIndexPath来获取第一个单元格。 Your code creates the cell and kicks off the async request for "Image 1" and stores it in your request var. 您的代码将创建该单元格,并启动对“图片1”的异步请求,并将其存储在您的请求变量中。

Then the collection view immediately calls cellForItemAtIndexPath again to get the second cell. 然后,收集视图立即再次调用cellForItemAtIndexPath以获取第二个单元格。 If the request for "Image 1" is still in progress, calling request?.cancel() interrupts it so "Image 1" will never finish downloading. 如果“ Image 1”的请求仍在进行中,则调用request?.cancel()会中断它,因此“ Image 1”将永远无法完成下载。 The code then creates a new request for "Image 2" and assigns it to request. 然后,代码为“图片2”创建一个新请求,并将其分配给请求。

The collection view immediately calls cellForItemAtIndexPath to get the third cell... 集合视图立即调用cellForItemAtIndexPath来获取第三个单元格。

One solution would be to store an array (or dictionary) of active requests. 一种解决方案是存储活动请求的数组(或字典)。 Add a request when you make it, remove it when the request completes (failure or success). 发出请求时添加请求,完成请求后将其删除(失败或成功)。 Then if you determine that there's a request in progress for a cell you're about to reuse, cancel that request and remove it from the list. 然后,如果您确定要重复使用的单元正在处理中,请取消该请求并将其从列表中删除。

Another way to do it would be to create a custom cell subclass and have it store the active request. 另一种方法是创建一个自定义单元子类,并使其存储活动请求。 This has the advantage of making it simpler to correlate requests to cells. 这具有使将请求与单元关联起来更简单的优点。

Using either approach, you may want to consider cancelling the active request for a cell in UICollectionViewCell.prepareForReuse() instead of cellForItemAtIndexPath. 使用这两种方法时,您可能要考虑取消对UICollectionViewCell.prepareForReuse()中单元格的活动请求,而不是取消cellForItemAtIndexPath。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM