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

Swift 6:非Sendable类型self在@Sendable闭包中被捕获的解决疑问

解决方法

1. 局部捕获Actor实例,避免捕获整个self

这是最直接的方案——把类里的worker属性先赋值给一个局部变量,再在Task闭包里使用这个局部变量。这样闭包只会捕获Sendable的Actor实例,而非非Sendable的self:

func swift6IsJustGreat()
{
    let localWorker = worker
    Task {
        let number: Int = await localWorker.doWork()
        print(number)
    }
}

Actor本身默认是Sendable类型,局部变量localWorker可以安全被@Sendable闭包捕获,不会触发错误。

2. 让MyClass遵守Sendable协议

如果MyClass的所有属性都是线程安全的(比如这里的worker是Actor,本身具备线程安全性),可以让类遵守Sendable协议:

  • 若MyClass不需要被继承,直接用final修饰并遵守协议:
final class MyClass: Sendable {
    let worker: MyActor = MyActor()
    
    func swift6IsJustGreat()
    {
        Task {
            let number: Int = await worker.doWork()
            print(number)
        }
    }
}
  • 若必须保留继承性,可使用@unchecked Sendable(但需自行保证类的所有状态都是线程安全的,避免数据竞争):
class MyClass: @unchecked Sendable {
    let worker: MyActor = MyActor()
    
    func swift6IsJustGreat()
    {
        Task {
            let number: Int = await worker.doWork()
            print(number)
        }
    }
}

3. 显式指定捕获列表

也可以通过捕获列表明确只捕获worker,而非隐式捕获self,效果和第一种方法一致,但写法更清晰:

func swift6IsJustGreat()
{
    Task { [worker] in
        let number: Int = await worker.doWork()
        print(number)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:52:38