如何在Swift 三、4和5中编写GCD中的dispatch_after?

在Swift 2中,我可以使用dispatch_after来经过中央中央调度来延迟动做: api

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中编写此代码的首选方法是什么? async


#1楼

调用DispatchQueue.main.after(when: DispatchTime, execute: () -> Void) ide

我强烈建议使用Xcode工具转换为Swift 3(“编辑”>“转换”>“转换为当前Swift语法”)。 它为我抓住了 工具


#2楼

语法很简单: spa

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

请注意,以上将seconds添加为Double语法彷佛使人感到困惑(特别是由于咱们习惯于添加nsec)。 之因此可使用“将秒数DoubleDouble ”语法,是由于deadlineDispatchTime而且在幕后有一个+运算符,它将占用Double并将那么多秒数加到DispatchTime.net

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

可是,若是您确实想向DispatchTime添加整数毫秒,μs或nsec,则还能够向DispatchTimeInterval添加DispatchTime 。 这意味着您能够: code

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类中+运算符使用了这种单独的重载方法,所以全部这些都能无缝运行。 get

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime

有人问如何取消已分派的任务。 为此,请使用DispatchWorkItem 。 例如,这将启动一个任务,该任务将在五秒钟内触发,或者若是视图控制器被解除并释放,则其deinit将取消该任务: it

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 )。 io


#3楼

斯威夫特4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

对于时间.seconds(Int) ,也可使用.microseconds(Int).nanoseconds(Int)


#4楼

若是您只想要延迟功能

斯威夫特4&5

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
     DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
          closure()
     }
}

您能够像这样使用它:

delay(interval: 1) { 
    print("Hi!")
}

#5楼

在Swift 3发布以后,还必须添加@escaping

func delay(_ delay: Double, closure: @escaping () -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
    closure()
  }
}
相关文章
相关标签/搜索