web-dev-qa-db-ja.com

ディスパッチグループ-メインスレッドに通知できません

Swift GCDの3つの進化を読んだ後、ディスパッチグループを作成しようとしています。問題はgroup.notify(queue:合格時に通知しないDispatchQueue.mainキューとして。ただし、バックグラウンドキューでは機能します。

また、コードをSwift 2からSwift 3.に変換しようとしているため、構文がすべて正しいかどうかもわかりません。

typealias CallBack = (result: Bool) -> Void
func longCalculations (completion: CallBack) {

let backgroundQ = DispatchQueue.global(attributes: .qosBackground)

    let group = DispatchGroup()  
    var fill:[Int] = [] 
    for item in 0...200 {
        group.enter() 
        if item > 50 {
            fill.append(item)
        }
        group.leave() 
    }

//Below in the notify argument If I pass `backgroundQ`, it seems to work correctly but not when DispatchQueue.main is passed.

このコードは機能しません

group.notify(queue: DispatchQueue.main, execute: {
    completion(result: true)
    })
 }

これは正しく動作します

group.notify(queue: backgroundQ, execute: {
    completion(result: true)
    })
 }
_______________________________________________________

longCalculations() { print($0) }
15
jyet

マットが提案した投稿を読んだところ、メインキューにタスクを送信していることがわかりました。メインスレッド自体で通知を要求すると、デッドロックが発生しました。

コードを変更しましたが、意図したとおりに機能しています。

typealias CallBack = (result: [Int]) -> Void
func longCalculations (completion: CallBack) {
  let backgroundQ = DispatchQueue.global(attributes: .qosDefault)
  let group = DispatchGroup()

  var fill:[Int] = []
  for number in 0..<100 {
      group.enter()
      backgroundQ.async(group: group,  execute: {  
          if number > 50 {
            fill.append(number)
          }
          group.leave()

          })
      }

     group.notify(queue: DispatchQueue.main, execute: {
       print("All Done"); completion(result: fill)
     }) 
}

longCalculations(){print($0)}
29
jyet