如何在新搜索上取消uitableviewcells的异步图像加载

时间:2017-12-28 17:14:38

标签: ios swift

我在服务器上开始搜索用户个人资料。当用户键入用户名时,不同的建议配置文件会显示在UITableView的单元格中。每个配置文件都有一个与之关联的图像。一旦用户键入,cellForItem(at:)功能就会异步加载图像。当用户键入搜索时,它会取消我对服务器的搜索请求,但是它也需要取消异步请求。一次可能会发生多个请求 - 我应该如何跟踪它们?

下载图片的代码如下:

model.downloadImage(
    withURL: urlString,
    completion: { [weak self] error, image in
    guard let strongSelf = self else { return }
        if error == nil, let theImage = image {
            // Store the image in to our cache
            strongSelf.model.imageCache[urlString] = theImage
            // Update the cell with our image
            if let cell = strongSelf.tableView.cellForRow(at: indexPath) as? MyTableCell {
                cell.profileImage.image = theImage
            }
        } else {
             print("Error downloading image: \(error?.localizedDescription)")
        }
    }
)

请注意,如果需要,我可以添加request = model.downloadImage(...,但request只会保留指向上次调用downloadImage()函数的指针。

2 个答案:

答案 0 :(得分:0)

为此,我建议使用Kingfisher。它是用于下载和缓存图像的强大的第三方库。使用翠鸟,您只需致电:

即可达到您想要的效果
// In table view delegate
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    //...
    cell.imageView.kf.cancelDownloadTask()
}

答案 1 :(得分:0)

你可以使用GCD,iOS 8&引入了macOS 10.10 DispatchWorkItem,它在一个非常易于使用的API中提供了这个确切的功能(可以取消它的任务)。

这是一个例子:

class SearchViewController: UIViewController, UISearchBarDelegate {
    // We keep track of the pending work item as a property
    private var pendingRequestWorkItem: DispatchWorkItem?
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        // Cancel the currently pending item
        pendingRequestWorkItem?.cancel()
        // Wrap our request in a work item
        let requestWorkItem = DispatchWorkItem { [weak self] in
            self?.model.downloadImage(...
        }
        // Save the new work item and execute it after 250 ms
        pendingRequestWorkItem = requestWorkItem
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250),
                                      execute: requestWorkItem)
    }
}

在您的情况下,您需要在用户输入信息时通过委托(例如:TextField)了解。