代码之家  ›  专栏  ›  技术社区  ›  Victor

Swift调度组在任务完成前通知

  •  8
  • Victor  · 技术社区  · 6 年前

    我正在使用 DispatchGroup 执行任务,但 group.notify 正在任务完成之前调用。

    我的代码:

    let group = DispatchGroup()
    let queueImage = DispatchQueue(label: "com.image")
    let queueVideo = DispatchQueue(label: "com.video")
    queueImage.async(group: group) {
        sleep(2)
        print("image")
    }
    
    queueVideo.async(group: group) {
        sleep(3)
        print("video")
    }
    
    group.notify(queue: .main) {
        print("all finished.")
    }
    

    日志:

    all finish.
    image
    video
    
    3 回复  |  直到 6 年前
        1
  •  17
  •   Smartcat    6 年前

    更新时间: 上述问题实际上按原样正确运行(正如rmaddy指出的!)

    我将这个错误答案保存在下面,以防其他人对DispatchQueue的异步(组:)方法行为感到困惑,因为 Apple's swift doc on it 目前很糟糕。


    在每次调用async()之前,需要调用组的enter(),然后在每个async()块的末尾调用组的leave(),但是 在内部 街区。它基本上就像一个refcount,当它达到零(没有输入剩余值)时,就会调用notify块。

    let group = DispatchGroup()
    let queueImage = DispatchQueue(label: "com.image")
    let queueVideo = DispatchQueue(label: "com.video")
    
    group.enter()
    queueImage.async(group: group) {
        sleep(2)
        print("image")
        group.leave()
    }
    
    group.enter()
    queueVideo.async(group: group) {
        sleep(3)
        print("video")
        group.leave()
    }
    
    group.notify(queue: .main) {
        print("all finished.")
    }
    
        2
  •  1
  •   iPhoneDeveloper    4 年前

    一般回答:(Swift 5)

    let yourDispatchGroup = DispatchGroup()
    
    yourDispatchGroup.enter()
    task1FunctionCall {
      yourDispatchGroup.leave() //task 1 complete
    }
    
    yourDispatchGroup.enter()
    task2FunctionCall {
      yourDispatchGroup.leave() //task 2 complete
    }
    
    .. ..
    yourDispatchGroup.enter()
    tasknFunctionCall {
      yourDispatchGroup.leave() //task n complete
    }
    
    dispatchGroup.notify(queue: .main) {
      //This is invoked when all the tasks in the group is completed.
    }
    
        3
  •  0
  •   pableiros Jatin Arora    3 年前

    如果您的 DispatchGroup 是一个 lazy var ,尽量不要调用 notify 方法。

    lazy var dispatchGroup: DispatchGroup = {
        let dispatchGroup = DispatchGroup()
        
        // not call here dispatchGroup.notify(...
    
        return dispatchGroup
    }()
    

    你需要打电话给所有 enter 方法之前的 通知 方法:

    dispatchGroup.enter()
    
    dispatchQueue.async(group: dispatchGroup) {
        // ...
        self.dispatchGroup.leave()
    }
    
    dispatchGroup.notify(queue: .main) {
        print("all finished.")
    }