在Swift 2中,我能够使用dispatch_after
延迟使用中央调度的操作:
var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// your function here
})
但自Swift3以来,这似乎不再编译了。用现代Swift写这篇文章的首选方式是什么?
语法很简单:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
注意,上面将seconds
添加为double
的语法似乎是一个混乱的来源(特别是因为我们已经习惯了添加nsec)。“add seconds asdouble
”语法起作用,因为deadly
是一个dispatchtime
并且在幕后,有一个+
运算符将使用double
并向dispatchtime
添加那么多秒:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
但是,如果您确实想向DispatchTime
添加毫秒、微秒或nsec的整数,您也可以向DispatchTime
添加DispatchTimeInterval
。这意味着您可以:
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
。例如,这将启动一个将在五秒内触发的任务,或者如果视图控制器被解除并释放,则其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() { ... }
}
请注意在DispatchWorkItem
中使用了[weak self]
捕获列表。这对于避免强参考周期至关重要。还要注意,这并不是抢先取消,而是在任务尚未启动时停止它。但是,如果在遇到cancel()
调用时它已经启动,则块将完成其执行(除非您手动检查块内的iscancelled
)。
雨燕4:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
// Code
}
也可以使用.seconds(Int)
、.microseconds(Int)
和.nanseconds(Int)
。
如果只希望延迟函数
Swift 4和5
func delay(interval: TimeInterval, closure: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
closure()
}
}
您可以这样使用它:
delay(interval: 1) {
print("Hi!")
}