我有多个任务要放在后台线程中运行的串行/并发队列中。每个任务都将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)
}
}
答案 0 :(得分:3)
我们可以从您的症状中推断出InitData.fetch
有两个参数:一个字符串("someUrl"
)和一个回调,并且它将回调提交给主队列执行。调用InitData.fetch
时,您所在的队列无关紧要。重要的是InitData
最终(异步)用于调度回调执行的队列。也许您可以告诉它您希望它使用哪个队列,但显然在您编写的程序中,它使用主队列。