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

Swift 4中线程1等待线程2执行的多线程同步问题咨询

Swift 4多线程同步:实现线程等待逻辑

看起来你已经选对了方向——用DispatchGroup来处理多线程同步问题,这是Apple官方推荐的解决这类"等待一组任务完成"场景的方案。我帮你补全代码并解释核心逻辑,完美解决线程等待的需求。

核心思路

DispatchGroup的工作原理很简单:

  • 每启动一个需要等待的异步任务前,调用enter()(相当于告诉Group"我要开始一个任务了")
  • 任务完成后,调用leave()(告诉Group"我的任务做完了")
  • 当所有enter()的任务都调用了leave(),Group就会触发notify闭包,或者解除wait()的阻塞

根据你的需求,分两种常见场景实现:


场景1:两个任务并行执行,都完成后再执行后续逻辑

如果你的需求是doSomethingFromJSON1和doSomethingFromJSON2可以并行跑,但必须等它们都完成后,再执行downloadImage、lastThread等后续任务,代码如下:

func doSomethingFromJSON1() { print("1") }
func doSomethingFromJSON2() { print("2") }
func downloadImage() { print("3") }
func waitingForNext() { print("4 - waiting") }
func lastThread(){ print("Last THREAD") }
func finishFunction(){ print("Finish") }

func doItAll() { 
    let dispatchGroup = DispatchGroup()

    // 任务1:doSomethingFromJSON1
    dispatchGroup.enter()
    DispatchQueue.global().async {
        // 用defer保证即使任务抛出异常,leave也会被调用
        defer { dispatchGroup.leave() }
        self.doSomethingFromJSON1()
    }

    // 任务2:补全你未完成的doSomethingFromJSON2逻辑
    dispatchGroup.enter()
    DispatchQueue.global().async {
        defer { dispatchGroup.leave() }
        self.doSomethingFromJSON2()
    }

    // 非阻塞式等待:所有任务完成后,在指定队列执行后续逻辑
    dispatchGroup.notify(queue: DispatchQueue.global()) {
        // 前两个任务都完成了,执行downloadImage
        self.downloadImage()
        
        // 如果waitingForNext也需要异步执行并等待,继续用Group
        let innerGroup = DispatchGroup()
        innerGroup.enter()
        DispatchQueue.global().async {
            defer { innerGroup.leave() }
            self.waitingForNext()
        }

        // 最后回到主线程执行收尾(比如更新UI)
        innerGroup.notify(queue: DispatchQueue.main) {
            self.lastThread()
            self.finishFunction()
        }
    }
}

场景2:线程1(doSomethingFromJSON1)必须等待线程2(doSomethingFromJSON2)完成后才启动

如果你的需求是明确的"线程1要等线程2做完才能开始",可以简化逻辑,把线程1的任务放在线程2完成后的通知闭包里:

func doItAll() { 
    let dispatchGroup = DispatchGroup()

    // 先启动线程2的任务
    dispatchGroup.enter()
    DispatchQueue.global().async {
        defer { dispatchGroup.leave() }
        self.doSomethingFromJSON2() // 线程2执行
    }

    // 等待线程2完成后,启动线程1
    dispatchGroup.notify(queue: DispatchQueue.global()) {
        self.doSomethingFromJSON1() // 线程1现在才开始执行
        
        // 线程1完成后,继续后续任务
        self.downloadImage()
        self.waitingForNext()
        
        // 回到主线程收尾
        DispatchQueue.main.async {
            self.lastThread()
            self.finishFunction()
        }
    }
}

关键注意事项

  • enter()和leave()必须成对出现:如果enter()比leave()多,Group会永远等待;如果leave()多,会导致崩溃。用defer包裹leave()是最安全的方式,能避免异常或提前返回导致的遗漏。
  • 避免在主线程调用wait():wait()会阻塞当前线程,如果在主线程调用,会导致UI冻结,用户体验极差。优先用notify()这种非阻塞方式。
  • 队列选择:异步任务尽量放在全局后台队列(DispatchQueue.global()),涉及UI更新的收尾逻辑一定要切回主线程(DispatchQueue.main)。

内容的提问来源于stack exchange,提问作者Łukasz Betta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:37:25