如何在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()
  }
}
相關文章
相關標籤/搜索