タスクが完了するまで待機する 質問する

タスクが完了するまで待機する 質問する

タスクがDispatchQueue終了するまでコードを待機させるにはどうすればよいですか? 完了ハンドラーなどが必要ですか?

func myFunction() {
    var a: Int?

    DispatchQueue.main.async {
        var b: Int = 3
        a = b
    }

    // Wait until the task finishes, then print.

    print(a) // This will contain nil, of course, because it
             // will execute before the code above.

}

私は Xcode 8.2 を使用して Swift 3 で書いています。

ベストアンサー1

の非同期性をmyFunction呼び出し元から隠す必要がある場合は、DispatchGroups を使用してこれを実現します。それ以外の場合は、完了ブロックを使用します。両方のサンプルを以下で見つけてください。


ディスパッチグループサンプル

グループの通話のバランスが取れたときに通知を受け取ることができenter()ますleave():

func myFunction() {
    var a = 0

    let group = DispatchGroup()
    group.enter()

    DispatchQueue.main.async {
        a = 1
        group.leave()
    }

    // does not wait. But the code in notify() is executed 
    // after enter() and leave() calls are balanced

    group.notify(queue: .main) {
        print(a)
    }
}

または待つこともできます:

func myFunction() {
    var a = 0

    let group = DispatchGroup()
    group.enter()

    // avoid deadlocks by not using .main queue here
    DispatchQueue.global(qos: .default).async {
        a = 1
        group.leave()
    }

    // wait ...
    group.wait()
    
    print(a) // you could also `return a` here
}

注記:group.wait()現在のキュー(おそらくあなたの場合はメインキュー)をブロックするので、dispatch.async別のキュー(上記のサンプルコードのように)でブロックして回避する必要があります。行き詰まり


完了ブロックのサンプル

func myFunction(completion: @escaping (Int)->()) {
    var a = 0

    DispatchQueue.main.async {
        let b: Int = 1
        a = b
        completion(a) // call completion after you have the result
    }
}

// on caller side:
myFunction { result in
    print("result: \(result)")
}

おすすめ記事