Dispatch队列阻塞主线程

时间:2018-01-17 07:24:48

标签: ios swift

我有多个任务要放在后台线程中运行的串行/并发队列中。每个任务都将fetch数据来自api(异步)然后copyItem(同步,取决于fetch的res)。下面的代码阻止主线程。但是,如果我只将copyItem分配给队列,则不会阻止主线程。为什么我不能在后台线程中运行整个块?

let serialQueue = DispatchQueue(label: "queue", qos: .background)
tableView.selectedRowIndexes.forEach { row in

  serialQueue.async {   

    InitData.fetch("someUrl") { initData in
      let fileManager = FileManager()                
      do {
         try fileManager.copyItem(atPath: "pathA", toPath: "pathB")
      } catch let error {
         print(error)
      }
    }
  }
}

这不会阻止主线程:

tableView.selectedRowIndexes.forEach { row in

  InitData.fetch("someUrl") { initData in
    let fileManager = FileManager()
    let workItem = DispatchWorkItem {          
      do {
        try fileManager.copyItem(atPath: "pathA", toPath: "pathB")
      } catch let error {
        print(error)
      }
    }
    DispatchQueue.global(qos: .background).async(execute: workItem)
  }
}

1 个答案:

答案 0 :(得分:3)

我们可以从您的症状中推断出InitData.fetch有两个参数:一个字符串("someUrl")和一个回调,并且它将回调提交给主队列执行。调用InitData.fetch时,您所在的队列无关紧要。重要的是InitData最终(异步)用于调度回调执行的队列。也许您可以告诉它您希望它使用哪个队列,但显然在您编写的程序中,它使用主队列。