You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:40:34