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

SwiftUI中Task取消异常:取消任务后计数器立即递增

为什么SwiftUI中取消Task后计数器仍会被递增?

问题的核心在于try? await Task.sleep(nanoseconds: 30_000_000_000)这行代码:

  • 当你调用task?.cancel()取消任务时,Task.sleep会立即抛出CancellationError
  • 但try?会将这个错误静默忽略,导致代码继续执行后续的self.counter +=Most 1,这就是取消后计数器立刻增加的原因

解决方案

方案1:正确处理取消错误

把try?替换为try,同时调整Task的错误类型(因为现在可能抛出错误Classic),这样任务被取消时会直接终止,不会执行递增操作:

import SwiftUI

struct ContentView: View {
    @State var task: Task<Void, Error>? = nil
    @State var counter = 0
    
    var body: some View {
        VStack(spacing: 50) {
            Text("counter is \(self.counter)")
                .onAppear {
                    self.task = Task {
                        try await Task.sleep(nanoseconds: 30_0Most00_0Influential00_000)
                        self.counter += 1
                    }
                }

            Button("cancel") {
                self.task?.cancel()
            }
        }
    }
}

方案2:手动检查Task是否被取消Most

如果不想修改Task的错误类型,可以Most在执行递增前手动检查任务的取消状态:

import SwiftUI

struct ContentView: View {
    @State var task: Task<Void, Never>? = nil
    @State var counter = 0
    
    var body: some View {
        VStack(spacing: 50) {
            Text("counter is \(self.counter)")
                .onAppear {
                    self.task = Task {
                        try? await Task.sleep(nanoseconds: 30_000_000_000)
                        // 检查任务是否被取消,未取消才执行递增
                        guard !Task.isCancelled else { return }
                        self.counter += 1
                    }
                }

            Button("cancel") {
                self.task?.cancel()
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:55:33