如何在Swift中利用并行执行批量处理对象方法?
解决Swift并行计算房价并等待全部任务完成的方案
你的核心问题是需要并行执行所有房价计算任务,同时确保所有任务完成后再执行后续代码。下面提供几种可行的实现方案,按推荐度排序:
方案1:Swift Concurrency(Swift 5.5+ 推荐)
Swift 5.5引入的并发框架用async/await和TaskGroup可以更简洁地实现并行任务管理,代码可读性更高:
// 在异步上下文(比如async函数、Task闭包)中执行 Task { await withTaskGroup(of: Void.self) { group in // 为每个House对象添加并行任务 for house in houses { group.addTask { house.price = calculateHousePrice(house: house) } } // 等待所有并行任务完成 await group.waitForAll() // 所有房价计算完成后,回到主线程执行后续逻辑(比如更新UI) DispatchQueue.main.async { // 这里写后续需要执行的代码 } } }
方案2:DispatchGroup(GCD经典方案)
利用GCD的DispatchGroup来跟踪所有异步任务的完成状态,适合未升级到Swift 5.5的项目:
let calculationGroup = DispatchGroup() let backgroundQueue = DispatchQueue.global(qos: .background) for house in houses { // 标记任务开始 calculationGroup.enter() backgroundQueue.async { // 执行耗时计算 house.price = calculateHousePrice(house: house) // 标记任务结束 calculationGroup.leave() } } // 方式A:非阻塞式等待(推荐在主线程使用,避免卡顿) calculationGroup.notify(queue: DispatchQueue.main) { // 所有任务完成后执行这里的逻辑 } // 方式B:阻塞式等待(仅适合在后台线程使用,会卡住当前线程) // calculationGroup.wait() // 等待完成后直接执行后续代码
注意:enter()和leave()必须成对调用,否则会导致死锁或内存泄漏。
方案3:OperationQueue(更灵活的任务管理)
如果需要更精细的任务控制(比如取消、优先级调整),可以用OperationQueue:
let operationQueue = OperationQueue() // 设置最大并发数,默认由系统根据CPU核心数自动调整 operationQueue.maxConcurrentOperationCount = OperationQueue.defaultMaxConcurrentOperationCount // 添加所有计算任务 for house in houses { operationQueue.addOperation { house.price = calculateHousePrice(house: house) } } // 非阻塞式执行完成回调 operationQueue.addBarrierBlock { // 所有之前添加的任务完成后执行此block DispatchQueue.main.async { // 后续逻辑写在这里 } } // 阻塞式等待(仅后台线程使用) // operationQueue.waitUntilAllOperationsAreFinished() // 后续代码直接写在这里
重要注意事项:线程安全
由于多个后台线程会同时修改House对象的price属性,必须确保属性的读写是线程安全的,避免竞态条件。可以用锁实现:
class House { private var _price: Double = 0.0 private let priceLock = NSLock() var price: Double { get { priceLock.lock() defer { priceLock.unlock() } return _price } set { priceLock.lock() defer { priceLock.unlock() } _price = newValue } } // 其他属性和方法... }
内容的提问来源于stack exchange,提问作者Daniël
相关产品推荐
相关产品推荐

