You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何取消之前的异步请求?解决UITableView下拉刷新重复数据问题

解决UITableView下拉刷新重复请求与重复条目的问题

方案一:取消旧的网络请求

每次触发下拉刷新时,先终止未完成的旧请求,再发起新请求,从根源上避免重复回调。

  • 先定义变量保存当前活跃的请求:
    var currentRequest: URLSessionDataTask?
    
  • 在下拉刷新的处理方法中执行取消+新建逻辑:
    func handleRefresh() {
        // 取消之前未完成的请求
        currentRequest?.cancel()
        // 创建并发起新请求
        currentRequest = URLSession.shared.dataTask(with: yourRequest) { [weak self] data, response, error in
            guard let self = self, error == nil, let data = data else { return }
            // 仅处理最新请求的返回数据
            DispatchQueue.main.async {
                self.dataArray = self.parseData(data) // 解析数据替换旧列表
                self.tableView.reloadData()
                self.refreshControl?.endRefreshing()
            }
        }
        currentRequest?.resume()
    }
    

方案二:用版本号过滤旧请求结果

如果无法直接取消请求(比如使用第三方网络库),可以通过版本标记忽略过时的回调。

  • 定义一个版本计数器:
    var currentRequestVersion = 0
    
  • 发起请求时记录当前版本,回调时校验版本是否有效:
    func handleRefresh() {
        currentRequestVersion += 1
        let requestVersion = currentRequestVersion
        
        // 发起异步获取请求
        yourCustomFetchMethod { [weak self] newItems in
            guard let self = self else { return }
            // 只处理版本号匹配的最新请求结果
            if requestVersion == self.currentRequestVersion {
                DispatchQueue.main.async {
                    self.dataArray = newItems // 替换数据避免重复
                    self.tableView.reloadData()
                    self.refreshControl?.endRefreshing()
                }
            }
        }
    }
    

方案三:用OperationQueue管理请求

将每个异步请求包装成操作,加入队列,每次刷新时清空队列中未执行的操作。

  • 定义操作队列:
    let requestQueue = OperationQueue()
    
  • 处理刷新时管理队列操作:
    func handleRefresh() {
        // 取消队列中所有未完成的操作
        requestQueue.cancelAllOperations()
        
        let fetchOperation = BlockOperation { [weak self] in
            // 执行数据获取逻辑
            let newData = self?.fetchExtraEntries()
            DispatchQueue.main.async {
                guard let self = self, let newData = newData else { return }
                self.dataArray = newData
                self.tableView.reloadData()
                self.refreshControl?.endRefreshing()
            }
        }
        requestQueue.addOperation(fetchOperation)
    }
    
    注:如果是异步网络请求,建议自定义AsynchronousOperation子类,确保操作能正确等待请求完成。

额外提醒

  • 更新数据时优先用替换而非追加逻辑(如果下拉刷新是获取最新完整数据),或添加去重判断避免重复条目。
  • 异步回调中务必使用weak self,防止循环引用导致内存泄漏。

内容的提问来源于stack exchange,提问作者avregi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:29:56