Swift async/await中,能否将内部同步类标记为@unchecked Sendable?
关于内部同步引用类型标记
@unchecked Sendable的问题解答 核心结论
可以给这类内部同步的引用类型标记@unchecked Sendable,当作普通Sendable类型使用,但要分场景判断风险:
1. 系统提供的线程安全类(如UserDefaults)
这类系统类的线程安全性已经由Apple官方保证,虽然编译器没有自动推断其符合Sendable,但手动标记@unchecked Sendable是完全安全的,不会在async/await环境中产生不可预测的bug。Apple的系统类内部同步逻辑已经适配了Swift并发的调度机制,不用担心优先级反转或线程挂起的问题。
2. 自定义的内部同步类型(如用NSLock实现的DemoPerson)
标记@unchecked Sendable是可行的,但必须满足一个前提:你能100%确保自身的同步逻辑没有漏洞:
- 所有访问、修改内部状态的代码路径,都必须被锁(或串行队列)正确保护,不能有任何遗漏的未同步操作;
- 要避免锁的嵌套使用,尤其注意不要在持有锁的同步代码块内调用async函数——这会导致线程挂起,锁无法及时释放,大概率引发死锁或性能问题;
- Apple不建议在新代码中用锁,是指优先选择Swift并发原生的
actor、Task等机制,而非禁止旧的线程安全类型使用。只要你的自定义类型同步逻辑严谨,标记后当作Sendable使用不会有问题,但后续重构时建议逐步迁移到原生并发安全类型。
额外注意事项
标记@unchecked Sendable后,编译器会跳过Sendable的自动校验,所以一定要做好代码审查:
- 如果自定义类型的同步逻辑存在瑕疵(比如某个状态修改没加锁),那么在async/await的并发环境下,必然会出现数据竞争等不可预测的bug——这不是标记
@unchecked Sendable导致的,而是自身同步逻辑的问题。
内容的提问来源于stack exchange,提问作者fei
相关产品推荐
相关产品推荐

