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

Swift中处理Web查询后如何延迟调用endRefreshing并解决相关异常

问题原因

  • 短时间内多次触发下拉刷新会导致didUpdateAlerts被多次调用,你现有的实现没有取消之前提交的延迟任务,多个任务先后执行就会出现打印多次、延迟时长不符合预期的问题
  • UITableView.reloadData()是异步操作,调用后不会立刻完成列表渲染,你现有代码的计时起点是reloadData()的调用时间,不是列表真正完成刷新的时间

修复方案

你可以用可取消的DispatchWorkItem管理延迟任务,同时可以搭配CATransaction捕获列表刷新完成的时机,实现精准延迟:

  1. 首先在控制器类中声明一个变量存储延迟任务:
private var endRefreshWorkItem: DispatchWorkItem?
  1. 修改didUpdateAlerts的实现:
func didUpdateAlerts(alerts: [String:String]){
    DispatchQueue.main.async {
        // 取消之前未执行的结束刷新任务,避免多次调用冲突
        self.endRefreshWorkItem?.cancel()
        
        self.serviceDictionary = alerts
        self.tableView.reloadData()
        
        // 构建新的结束刷新任务
        let workItem = DispatchWorkItem { [weak self] in
            guard let self = self, self.refreshAlertsControl.isRefreshing else { return }
            self.refreshAlertsControl.endRefreshing()
            print("After 1 sec delay - alertRefresh")
        }
        self.endRefreshWorkItem = workItem
        
        // 等待列表渲染完成后再开始计时
        CATransaction.begin()
        CATransaction.setCompletionBlock {
            // 延迟1秒执行结束刷新逻辑
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: workItem)
        }
        CATransaction.commit()
    }
}
  1. 可选:在控制器销毁时取消未执行的任务,避免不必要的资源占用:
deinit {
    endRefreshWorkItem?.cancel()
}

如果你不需要严格对齐列表渲染完成的时机,也可以直接去掉CATransaction相关代码,直接提交延迟任务即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:24:01