Swift Actor在委托外观中的应用:是否避免activeTask数据竞争?
回答
你的理解完全正确。
核心原因:Actor的串行执行特性避免数据竞争
BluetoothLEScanWrapper 作为Actor,其所有方法(包括scan)的执行都是串行化的:
- 当多个异步调用同时触发
scan方法时,Actor会保证这些调用按顺序执行,同一时间只有一个调用能进入scan的逻辑流程。 - 如果没有Actor的保护,多线程环境下多个调用可能同时检查
activeTask是否为nil,进而同时创建新的Task并赋值给activeTask,这会引发双重问题:一是同时启动多个蓝牙扫描任务(违背“同一时间仅一个扫描任务运行”的业务逻辑),二是activeTask的状态会被错误覆盖,出现数据竞争。
额外的状态安全保障
除了activeTask,Actor还顺带保护了bluetoothLEDelegate内部的可变状态(比如foundPeripheral):
- 扫描过程中
foundPeripheral会被持续修改,扫描结束后又会被清空;如果没有Actor的串行访问机制,这些操作可能和其他线程的访问(比如新发起的scan调用)产生竞争,导致数据不一致或逻辑异常。
复用已有任务的逻辑可靠性
scan方法里“检测到已有activeTask则复用结果”的逻辑,也完全依赖Actor的串行执行特性——这保证了“检查activeTask是否为空”和“创建新任务并赋值”的操作是原子性的,不会出现“检查时activeTask为nil,但创建任务前被其他调用抢先赋值”的竞态条件。
内容的提问来源于stack exchange,提问作者isenwald2022
相关产品推荐
相关产品推荐

