在DispatchQueue.concurrentPerform闭包内实现并行执行的技术问询
实现单迭代内双函数并行执行的几种方案
针对你在DispatchQueue.concurrentPerform的每个迭代中,需要让funcA和funcB并行执行、等待两者完成后再进行后续判断的需求,以下是几种实用的实现方式:
方案一:使用DispatchGroup(GCD传统方式)
通过DispatchGroup管理两个并行任务,确保两者都完成后再执行后续逻辑:
private func testFunc(inputArray: [Int]) { let dataIterationArray = Array(Set(inputArray)) DispatchQueue.concurrentPerform(iterations: dataIterationArray.count) { index in let group = DispatchGroup() var funcAResult = false var funcBResult = false // 异步执行funcA并加入group group.enter() DispatchQueue.global().async { funcAResult = funcA(inputArray: dataIterationArray, startValue: 10, endValue: 2_000_000) group.leave() } // 异步执行funcB并加入group group.enter() DispatchQueue.global().async { funcBResult = funcB(inputArray: dataIterationArray, startValue: 5, endValue: 9) group.leave() } // 等待两个任务全部完成 group.wait() // 后续判断逻辑 if funcAResult && funcBResult { print("Yup we are good!") } else { print("Nope") } } }
关键点说明:
group.enter()标记任务开始,group.leave()标记任务结束,必须保证两者调用次数完全匹配group.wait()会阻塞当前线程(此处为concurrentPerform分配的后台线程),不会影响主线程运行- 两个函数分别在全局队列异步执行,实现真正的并行处理
方案二:使用OperationQueue
通过OperationQueue管理任务队列,利用waitUntilAllOperationsAreFinished()等待任务完成:
private func testFunc(inputArray: [Int]) { let dataIterationArray = Array(Set(inputArray)) DispatchQueue.concurrentPerform(iterations: dataIterationArray.count) { index in let queue = OperationQueue() queue.maxConcurrentOperationCount = 2 // 允许同时执行两个任务 var funcAResult = false var funcBResult = false // 添加funcA任务到队列 let operationA = BlockOperation { funcAResult = funcA(inputArray: dataIterationArray, startValue: 10, endValue: 2_000_000) } queue.addOperation(operationA) // 添加funcB任务到队列 let operationB = BlockOperation { funcBResult = funcB(inputArray: dataIterationArray, startValue: 5, endValue: 9) } queue.addOperation(operationB) // 等待队列中所有任务执行完毕 queue.waitUntilAllOperationsAreFinished() // 后续判断逻辑 if funcAResult && funcBResult { print("Yup we are good!") } else { print("Nope") } } }
关键点说明:
OperationQueue默认管理系统线程池,设置maxConcurrentOperationCount可控制并发任务数量- 适合需要精细控制任务优先级、依赖关系的场景
方案三:使用Swift Async/Await(现代Swift方式)
如果项目基于iOS 15+/macOS 12+,推荐使用更简洁的async/await语法,代码可读性更高:
// 方式1:将原函数改为异步函数 private func funcA(inputArray: [Int], startValue: Int, endValue: Int) async -> Bool{ for index in startValue...endValue { let dataValue = inputArray[index] if dataValue == 1_000_000 { return true } } return false } private func funcB(inputArray: [Int], startValue: Int, endValue: Int) async -> Bool{ for index in startValue...endValue { let dataValue = inputArray[index] if dataValue == 10 { return true } } return false } // 修改testFunc逻辑 private func testFunc(inputArray: [Int]) { let dataIterationArray = Array(Set(inputArray)) DispatchQueue.concurrentPerform(iterations: dataIterationArray.count) { index in Task { // 并行启动两个异步任务 async let resultA = funcA(inputArray: dataIterationArray, startValue: 10, endValue: 2_000_000) async let resultB = funcB(inputArray: dataIterationArray, startValue: 5, endValue: 9) // 等待两者结果返回 let (funcAResult, funcBResult) = await (resultA, resultB) // 后续判断逻辑 if funcAResult && funcBResult { print("Yup we are good!") } else { print("Nope") } } } }
关键点说明:
async let可同时启动多个异步任务,实现并行执行- 若不想修改原函数,可用
Task.detached包装同步调用:async let resultA = Task.detached { funcA(inputArray: dataIterationArray, startValue: 10, endValue: 2_000_000) }.value async let resultB = Task.detached { funcB(inputArray: dataIterationArray, startValue: 5, endValue: 9) }.value
额外注意事项
DispatchQueue.concurrentPerform本身是同步调用,会阻塞调用它的线程,建议将testFunc放在后台队列执行,避免阻塞主线程:DispatchQueue.global().async { testFunc(inputArray: yourLargeArray) // 所有迭代完成后执行后续逻辑 DispatchQueue.main.async { // 如更新UI等操作 } }- 原代码中
Array(Set(inputArray))会打乱原数组顺序并去重,若不需要该逻辑,可直接使用原数组
内容的提问来源于stack exchange,提问作者mikemgg123
相关产品推荐
相关产品推荐

