[英]Will an item submitted to the main `DispatchQueue` ever interrupt currently executing code on the main thread?
以下代码用于在后台线程上执行长时间运行的计算:
enum CalculationInterface {
private static var latestKey: AnyObject? // Used to cancel previous calculations when a new one is initiated.
static func output(from input: Input, return: @escaping (Output?) -> ()) {
self.latestKey = EmptyObject()
let key = self.latestKey! // Made to enable capturing `self.latestKey's` value.
DispatchQueue.global().async {
do {
let output = try calculateOutput(from: input, shouldContinue: { key === self.latestKey }) // Function cancels by throwing an error.
DispatchQueue.main.async { if (key === self.latestKey) { `return`(output) } }
} catch {}
}
}
}
这个函数是从主线程调用的,如下所示:
/// Initiates calculation of the output and sets it to the result when finished.
private func recalculateOutput() {
self.output = .calculating // Triggers calculation in-progress animation for user.
CalculationInterface.output(from: input) { self.output = $0 } // Ends animation once set and displays calculated output to user.
}
我想知道是否有可能在主线程运行我的代码时执行推送到DispatchQueue.main
的闭包。 或者换句话说,在self.output = .calculating
但在self.latestKey
重新设置为新对象之前执行。 如果可以,则可以向用户显示陈旧的计算输出。
我想知道是否有可能在主线程运行我的代码时执行推送到
DispatchQueue.main
的闭包
不,这是不可能的。 主队列是串行队列。 如果代码在主队列上运行,则不能运行“其他”主队列代码。 您的DispatchQueue.main.async
实际上意味着:“等到在主队列上运行的所有代码自然结束,然后在主队列上运行它。”
另一方面, DispatchQueue.global()
不是串行队列。 因此,理论上有可能对calculateOutput
两个调用重叠。 这不是你想要发生的事情; 您希望确保任何正在执行的calculateOutput
实例在另一个实例可以启动之前完成(并且我们继续处理latestKey
)。 换句话说,您要确保序列
latestKey
calculateOutput
latestKey
连贯地发生。 确保这一点的方法是将您使用DispatchQueue(label:)
创建的DispatchQueue(label:)
放在一边,您将始终使用它来运行calculateOutput
。 默认情况下,该队列将是串行队列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.