在Swift 2中,我能够dispatch_after使用大型中央调度来延迟动作:
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 })
但是,自Swift 3起,似乎不再可以编译了。在现代Swift中编写此代码的首选方法是什么?
语法很简单:
// to run something in 0.1 seconds DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // your code here }
请注意,上述添加seconds为a的语法Double似乎是造成混乱的根源(特别是因为我们习惯于添加nsec)。Double之所以deadline可以使用“ add seconds as ”语法,是因为a DispatchTime和在幕后,有一个+运算符将占用a Double并将其增加很多秒DispatchTime:
seconds
Double
deadline
DispatchTime
+
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
但是,如果您确实想向加上毫秒,μs或nsec的整数DispatchTime,则也可以DispatchTimeInterval向加上a 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它将取消该任务:
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() { ... } }
请注意中使用[weak self]捕获列表DispatchWorkItem。这对于避免强大的参考周期至关重要。另请注意,这不会进行抢先取消,而只是在任务尚未开始时停止它的启动。但是,如果它在遇到cancel()调用时已经启动,则该块将完成其执行(除非您要手动检查isCancelled该块内部)。
[weak self]
cancel()
isCancelled