Swift:DispatchGroup.notify在任务完成前被调用的问题求助
问题分析与解决方案
你遇到的这个情况大概率是在Playground里测试代码导致的——Playground默认会在主线程初始任务执行完毕后就停止运行,不会等待后台异步任务完成,所以group.notify的闭包会被提前触发,而后台队列里的sleep任务还没来得及执行完毕。
快速解决办法
如果是在Playground中测试,只需要在代码开头添加以下两行,让Playground保持运行状态直到所有异步任务完成:
import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true
代码逻辑验证(普通App环境)
如果是在iOS/macOS App中运行你这段代码,逻辑本身是完全正确的:
- 调用
async(group:)时,DispatchGroup会自动执行enter()来增加任务计数 - 任务执行完毕后,DispatchGroup会自动调用
leave()减少计数 - 当所有加入group的任务都完成(计数归0),
notify的闭包才会在主线程触发
正常运行的输出顺序应该是:
image video all finished.
额外开发建议
尽量避免用sleep()模拟耗时操作,它会直接阻塞当前线程,不符合GCD的异步设计思路。实际开发中更推荐用DispatchQueue.asyncAfter或者其他异步耗时API,比如:
// 手动管理group的enter/leave(因为asyncAfter是嵌套异步任务) group.enter() queueImage.async { DispatchQueue.main.asyncAfter(deadline: .now() + 2) { print("image") group.leave() } } group.enter() queueVideo.async { DispatchQueue.main.asyncAfter(deadline: .now() + 3) { print("video") group.leave() } }
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

