Actor中的闭包:传递NonSendable为何在Swift 6中被禁止?
Swift 6中Actor内forEach闭包捕获NonSendable对象的编译错误原因
核心背景:Swift 6的并发安全强制检查
Swift 6大幅强化了并发安全的静态检查,要求跨隔离域传递的对象必须遵循Sendable协议(或被编译器证明天然线程安全)。示例中的NonSendable类未遵循Sendable,说明它的实例不具备线程安全性,无法安全地在不同隔离域间共享或并发访问。
两种循环的差异分析
普通for循环编译正常的原因
在foo()方法的普通for循环中,所有代码都直接运行在MyActor的隔离域内。actor的核心特性是串行执行所有方法和操作,这保证了对nonSendable的创建、传递给bar(_:)等所有操作都是串行进行的,完全不存在并发访问的可能,因此编译器判定这段代码安全。forEach闭包触发错误的原因
forEach接收的闭包虽然是同步执行的,但Swift 6的并发检查会将其视为一个独立的执行单元。当闭包捕获nonSendable这个非Sendable实例时,编译器无法通过静态分析消除以下风险:- 闭包的执行可能与其他actor的操作产生并发(哪怕当前代码是同步的,静态检查会考虑理论上的并发可能性);
- 闭包内对
nonSendable的访问,可能和后续对该变量的其他访问(即使当前代码中没有)产生数据竞争。
因此编译器直接抛出数据竞争的编译错误,阻止潜在的不安全代码。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

