【发布时间】:2019-04-09 07:09:43
【问题描述】:
在主线程以外的线程上更新 UI 是一个常见错误,可能会导致错过 UI 更新、视觉缺陷、数据损坏和崩溃。
https://developer.apple.com/documentation/code_diagnostics/main_thread_checker
例子:
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
DispatchQueue.main.async { // Correct
self.label.text = "\(data.count) bytes downloaded"
}
}
}
task.resume()
我的问题从这里开始——
当我们说.async 表示与.main 不同时(或不平行)时,我对上述陈述感到困惑。有人可以解释我的问题吗?
【问题讨论】:
-
DispatchQueue.main.async表示您在主队列中排队一个任务,而无需等待任务执行。主队列任务将自动在主线程上运行,由操作系统调度。 -
将每个
DispatchQueue视为工人。调用.async会在worker的TODO列表下添加一个任务,不要等待worker完成任务。DispathQueue.main是在主线程上工作的特定工作者。 -
.sync将阻塞线程,直到任务块完成执行。您可以在主线程以外的任何线程上调用.sync,因为不能阻塞主线程。这并不意味着您不能致电DispatchQueue.main.sync。您可以像在非主线程上调用任何自定义dispathQueue.sync一样调用DispatchQueue.main.sync。例如DispatchQueue(label: "bgqueue", qos: .background).async{ DispatchQueue.main.sync{} }没问题。但DispatchQueue.main.asycn{ DispatchQueue.main.sync{} }不是。 -
.sync通常不是很有用。如果您希望在主队列任务之后发生某些事情,您只需将“某事”也排队到主队列中。如果没有必要,不值得阻塞线程。 -
是的。在这种情况下,从
bgqueue向main发出一个任务,然后bgqueue被阻塞以等待main上的任务完成。
标签: ios swift grand-central-dispatch