我有多个任务要放在后台线程中运行的串行/并发队列中 . 每个任务都将来自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 回答
我们可以从你的症状中推断出
InitData.fetch
有两个参数:一个字符串("someUrl"
)和一个回调,并且它将回调提交给 the main queue 以便执行 . 当你拨打InitData.fetch
时,你在哪个队列并不重要 . 重要的是InitData
最终(异步)用于安排回调执行的队列 . 也许您可以告诉它您希望它使用哪个队列,但显然在您编写的程序中,它使用主队列 .