Swift 6迁移:Sendable上下文下弱委托的处理方案问询
解决Swift 6弱委托的Sendable可变属性错误
最简解决方案:标记委托属性为@MainActor
Swift 6的严格并发检查下,继承自NSObject的ServiceProvider自动符合Sendable协议,但可变的弱委托属性因缺乏线程安全保障触发报错。最贴合原有代码习惯且改动最小的方案是利用@MainActor约束委托的访问与调用——这完全符合委托模式通常在主线程交互的常规场景:
- 修改服务协议,给委托属性添加
@MainActor约束:
protocol ServiceDelegate: AnyObject { func doSomething() } @MainActor protocol ServiceProvidable { var delegate: ServiceDelegate? { get set } func load() }
- 实现类中的委托属性自动继承
@MainActor约束,仅需确保调用委托方法时处于主线程:
final class ServiceProvider: NSObject, ServiceProvidable, URLSessionDelegate { weak var delegate: ServiceDelegate? func load() { // 若load方法可能在后台线程被调用,包裹主线程任务 Task { @MainActor in delegate?.doSomething() } // 若确定load始终在主线程执行,直接保留原调用即可 // delegate?.doSomething() } }
该方案仅需给协议添加@MainActor,改动极小,无需重构大量业务代码。
跨线程场景的替代方案:线程安全的弱引用容器
如果你的委托需要跨线程设置或调用,可以自定义原子弱引用容器,手动保证线程安全,同时将类标记为@unchecked Sendable:
import os.lock // 线程安全的弱引用容器 final class AtomicWeak<T: AnyObject> { private var _value: T? private let lock = os_unfair_lock() var value: T? { get { os_unfair_lock_lock(&lock) defer { os_unfair_lock_unlock(&lock) } return _value } set { os_unfair_lock_lock(&lock) defer { os_unfair_lock_unlock(&lock) } _value = newValue } } init(value: T? = nil) { self._value = value } } protocol ServiceDelegate: AnyObject { func doSomething() } protocol ServiceProvidable { var delegate: ServiceDelegate? { get set } func load() } final class ServiceProvider: NSObject, ServiceProvidable, URLSessionDelegate, @unchecked Sendable { private let _delegate = AtomicWeak<ServiceDelegate>() var delegate: ServiceDelegate? { get { _delegate.value } set { _delegate.value = newValue } } func load() { delegate?.doSomething() } }
该方案通过锁保证委托属性的线程安全,避免并发冲突,适合需要跨线程操作委托的场景。
Swift 6下弱委托的更优实践
除了上述方案,也可以用闭包替代传统委托模式,简化代码结构:
final class ServiceProvider: NSObject, URLSessionDelegate, Sendable { @MainActor var onSomethingDone: (() -> Void)? func load() { Task { @MainActor in onSomethingDone?() } } }
这种方式无需定义额外协议,更简洁,但需注意闭包的循环引用问题,设置时要使用[weak self]捕获。若要最小改动原有代码,前面的@MainActor方案仍是最优选择。
内容的提问来源于stack exchange,提问作者sash
相关产品推荐
相关产品推荐

