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
相关产品推荐
相关产品推荐

