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

Swift中如何取消延迟执行的pushViewController操作?

解决方案

你可以通过DispatchWorkItem来持有待执行的延迟任务,需要取消时直接调用其cancel()方法即可彻底终止任务执行,具体实现如下:

实现步骤

  • 给当前控制器添加一个私有属性,用于存储第二页的待执行push任务
  • 触发pushSecondVC时创建DispatchWorkItem并存储,提交到主队列延迟执行
  • 触发pushFirstVC或者页面即将消失时,调用存储任务的cancel()方法并置空,终止待执行任务
  • 执行任务前先判断任务是否已被取消,避免无效执行

完整代码示例

class TestViewController: UIViewController {
    // 存储第二页的待执行push任务
    private var pushSecondTask: DispatchWorkItem?
    
    @IBAction func pushFirstVC() {
        // 先取消未执行的第二页push任务
        pushSecondTask?.cancel()
        pushSecondTask = nil
        
        DispatchQueue.main.async { [weak self] in
            self?.navigationController?.pushViewController(FirstViewController(), animated: true)
        }
    }
    
    @IBAction func pushSecondVC() {
        // 先取消之前可能存在的旧任务,避免重复触发
        pushSecondTask?.cancel()
        
        // 创建新的push任务
        let task = DispatchWorkItem { [weak self] in
            // 执行前判断任务是否已被取消,已取消则直接返回
            guard let self = self, !task.isCancelled else { return }
            self.navigationController?.pushViewController(SecondViewController(), animated: true)
            // 执行完成后清空任务
            self.pushSecondTask = nil
        }
        pushSecondTask = task
        
        // 提交到主队列延迟执行
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: task)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 页面即将消失时也取消所有待执行任务
        pushSecondTask?.cancel()
        pushSecondTask = nil
    }
}

补充说明

该方案可以覆盖所有需要取消的场景:

  1. 5秒内触发pushFirstVC时,第二页任务会被直接取消,不会执行push
  2. 5秒内用户pop离开当前页面,viewWillDisappear会触发取消逻辑,即使之后再回到当前页面,任务也不会重新执行
  3. 重复触发pushSecondVC时,会自动取消之前的旧任务,仅保留最后一次触发的任务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:15:08