语法很简单:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
请注意,上述添加seconds
为 a的语法Double
似乎是混淆的来源(尤其是因为我们习惯于添加 nsec)。“将秒数添加为Double
”语法之所以有效,是因为deadline
它是 aDispatchTime
并且在幕后,有一个+
运算符将采用 aDouble
并将那么多秒数添加到DispatchTime
:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
但是,如果您真的想将整数 msec、μs 或 nsec 添加到DispatchTime
,您也可以将 a 添加DispatchTimeInterval
到 a DispatchTime
。这意味着你可以这样做:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
os_log("500 msec seconds later")
}
DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
os_log("1m μs seconds later")
}
DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
os_log("1.5b nsec seconds later")
}
+
由于类中运算符的这种单独的重载方法,这些都可以无缝地工作DispatchTime
。
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
有人询问如何取消已分派的任务。为此,请使用DispatchWorkItem
. 例如,这将启动一个将在 5 秒内触发的任务,或者如果视图控制器被解除并释放,deinit
它将取消该任务:
class ViewController: UIViewController {
private var item: DispatchWorkItem?
override func viewDidLoad() {
super.viewDidLoad()
item = DispatchWorkItem { [weak self] in
self?.doSomething()
self?.item = nil
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
}
deinit {
item?.cancel()
}
func doSomething() { ... }
}
注意[weak self]
在DispatchWorkItem
. 这对于避免强参考循环至关重要。另请注意,这不会进行抢先取消,而只是阻止任务启动(如果尚未启动)。但是,如果它在遇到调用时已经启动,则cancel()
该块将完成其执行(除非您在isCancelled
块内手动检查)。