我意识到使用 DispatchQueue.main.asyncAfter(deadline: .now())
和 perform(_:with:afterDelay:0)
是有区别的当主队列“忙”时。
请注意,在我的情况下,perform(_:with:afterDelay:)
是从主队列调用的。
看起来 DispatchQueue.main.asyncAfter(deadline: .now())
在下一个运行循环中立即执行任务而不关心主队列但是 perform(_:with:afterDelay :)
0 延迟将等待并仅在主队列“空闲”时执行任务(可能不会在下一个运行循环中调用)。
根据 Apple 文档 perform(_:with:afterDelay:)
Specifying a delay of 0 does not necessarily cause the selector to be performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible.
我不确定我是否理解正确,所以任何人都可以帮我解释一下它们之间到底有什么区别吗? 尽快执行是什么意思?
我发现了同样的问题 here但似乎这不是我想要的。
最佳答案
我创建了这个独立测试来探索这个主题。
class ViewController: UIViewController {
@objc func test1(_ info: Any) {
guard let str = info as? String else { return }
sleep(1)
print(str)
if str != "selector 3" {
self.perform(#selector(test1), with: "selector 3", afterDelay: 0)
}
DispatchQueue.main.asyncAfter(deadline: .now()) {
sleep(1)
print("dispatch 4 queued by \(str)")
}
}
@IBAction func test(_ sender: UIButton) {
print("begin test")
self.perform(#selector(test1), with: "selector 1", afterDelay: 0)
DispatchQueue.main.asyncAfter(deadline: .now()) {
DispatchQueue.main.asyncAfter(deadline: .now()) {
sleep(1)
print("dispatch 3")
}
sleep(1)
print("dispatch 1")
}
self.perform(#selector(test1), with: "selector 2", afterDelay: 0)
DispatchQueue.main.asyncAfter(deadline: .now()) {
sleep(1)
print("dispatch 2")
}
print("end test")
}
}
结果输出:
begin test
end test
dispatch 1
dispatch 2
selector 1
selector 2
dispatch 3
dispatch 4 queued by selector 1
dispatch 4 queued by selector 2
selector 3
selector 3
dispatch 4 queued by selector 3
dispatch 4 queued by selector 3
注意事项:
begin test
和end test
在显示perform(_:with:afterDelay:)
和的任何其他输出之前打印DispatchQueue.main.asyncAfter
排队并稍后运行。- 前两个
DispatchQueue
在perform
之前运行,即使它们以不同的顺序排队也是如此。 - 所有打印相隔一秒,这意味着它们都在同一个队列中运行,等待前一个完成。
dispatch 3
不会跳到selector 1
和selector 2
之前,即使它在dispatch 1之前排队
打印。
结论:
Dispatch.main.asyncAfter
和perform(_:with:afterDelay:)
都将它们的选择器/闭包排队等待稍后执行。由于您在主线程上运行perform(_:with:afterDelay:)
,它使用主队列进行调度。- 出于某种(对我而言)未知的原因,
Dispatch.main.asyncAfter(0)
调用在perform(_:with:afterDelay:0)
调用之前排队,当在同一个运行循环中排队。注意:如果在Dispatch.main.asyncAfter
中添加任何延迟,它将在perform(_:with:afterDelay:)
之后排队。例如,尝试使用.now() + .milliseconds(1)
。 - 尽快执行 只是表示它们按队列顺序排队和处理的另一种说法。根据任务在前面队列中花费的时间,在最终处理任务之前可能需要多次运行运行循环。
关于IOS - DispatchQueue.main.asyncAfter(deadline : . now()) 和 perform(_:with:afterDelay:) 之间的区别,延迟为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52162558/