如何无需为每次调用包裹同步块,让类中所有方法在同一队列执行?
解决方案:将队列调度逻辑封装到类内部
要实现所有方法自动在同一队列执行,无需调用者手动包裹同步块,核心思路是把队列的调度逻辑封装在MyClass内部,对外暴露的业务方法自行处理队列跳转,让调用者只需关注业务逻辑即可。
改造后的MyClass实现
class MyClass { // 使用串行队列彻底避免并发问题,若需读写分离可改用并发队列配合barrier private static let queue = DispatchQueue(label: "myqueue") func functionSet1(value: String) { Self.queue.sync { // 这里写实际的数据源修改逻辑 print("执行functionSet1,value: \(value)") } } func functionGet1() -> Bool { return Self.queue.sync { // 这里写实际的数据源读取逻辑 print("执行functionGet1") return true } } func functionSet2(value: String) { Self.queue.sync { // 实际的数据源修改逻辑 print("执行functionSet2,value: \(value)") } } func functionGet2() -> Bool { return Self.queue.sync { // 实际的数据源读取逻辑 print("执行functionGet2") return true } } }
调用者(Invoker)的简化写法
class Invoker { let invokee: MyClass = MyClass() func call1() { let result = invokee.functionGet1() // 直接处理返回结果即可 } func call2() { let result = invokee.functionGet2() } func call3() { invokee.functionSet1(value: "value") } func call4() { invokee.functionSet1(value: "another value") } }
关键说明
- 封装性:将队列设为
private,避免外部直接操作队列,保证类内部的并发控制逻辑不被破坏。 - 队列选择:
- 若所有操作(读写)都需要严格串行,用串行队列最直接,完全杜绝并发冲突。
- 若想优化读性能(允许多个读操作并发,写操作串行),可改用并发队列,写操作使用
sync(flags: .barrier):private static let queue = DispatchQueue(label: "myqueue", attributes: .concurrent) func functionSet1(value: String) { Self.queue.sync(flags: .barrier) { // 写操作逻辑 } } func functionGet1() -> Bool { return Self.queue.sync { // 读操作逻辑 return true } }
- 同步/异步选择:
- 有返回值的方法必须用
sync,因为需要等待队列执行完成后获取结果。 - 无返回值的写操作,若不需要等待执行完成,可改用
async提升调用方的响应性,但要注意业务是否允许异步执行。
- 有返回值的方法必须用
内容的提问来源于stack exchange,提问作者dubbeat
相关产品推荐
相关产品推荐

