For 循环中的 DispatchGroup

ble*_*erj 3 asynchronous grand-central-dispatch swift

所以,我有一段时间试图让 DispatchGroup 在长时间的异步操作完成之前阻止 for 循环进行迭代。我发现的大多数示例都相当简单明了,但我似乎无法让我的简单测试用例按预期工作。

let group = DispatchGroup()

    for i in 1...3 {
        group.enter()
        print("INDEX \(i)")
        asynchronousOperation(index: i, completion: {
            print("HELLO \(i)")
            self.group.leave()

        })
        print("OUTSIDE \(i)")
    }


func asynchronousOperation(index: Int, completion: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+5) {
        print("DONE \(index)")
        completion()

    }
}
Run Code Online (Sandbox Code Playgroud)

这最终打印

START
INDEX 1
OUTSIDE 1
INDEX 2
OUTSIDE 2
INDEX 3
OUTSIDE 3
DONE 1
HELLO 1
DONE 2
HELLO 2
DONE 3
HELLO 3
Run Code Online (Sandbox Code Playgroud)

我原以为它会打印出更像的东西

START
INDEX 1
OUTSIDE 1
HELLO 1
INDEX 2
OUTSIDE 2
HELLO 2
INDEX 3
OUTSIDE 3
HELLO 3
Run Code Online (Sandbox Code Playgroud)

只要在 asynchronousOperation() 内部调用 group.leave() 之后,就不会打印 OUTSIDE 之后的下一个“INDEX”

可能是我误解了一些简单的东西 - 有什么想法吗?

Kum*_*ddy 5

执行以下代码以获得正确的输出:

for i in 1...3 {
    let semaphore = DispatchSemaphore(value: 0) // create a semaphore with a value 0. signal() will make the value 1.
    print("INDEX \(i)")
    asynchronousOperation(index: i, completion: {
        print("HELLO \(i)")
        semaphore.signal() // once you make the signal(), then only next loop will get executed.
    })
    print("OUTSIDE \(i)")
    semaphore.wait() // asking the semaphore to wait, till it gets the signal.
}

   func asynchronousOperation(index: Int, completion: @escaping () -> ()) {
    DispatchQueue.global().asyncAfter(deadline: DispatchTime.now()+5) {
        print("DONE \(index)")
        completion()
    }
}
Run Code Online (Sandbox Code Playgroud)

输出 :

索引 1 外部 1 完成 1 你好 1

索引 2 外部 2 完成 2 你好 2

索引 3 外部 3 完成 3 你好 3