Как написать dispatch после GCD в Swift 3 и 4?

в Swift 2 я смог использовать dispatch_after чтобы отложить действие с помощью grand central dispatch:

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 (или 4). Каков предпочтительный способ написать это в Swift 3 (используя новый API отправки)?

11 ответов


синтаксис-это просто:

// to run something in 0.1 seconds

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

Примечание, приведенный выше синтаксис добавления seconds как Double кажется источником путаницы (esp, так как мы привыкли добавлять nsec). Что " добавить секунды как Double" синтаксис работает, потому что deadline это DispatchTime и, за кулисами, есть + оператор, который будет принимать Double и добавьте это много секунд к DispatchTime:

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

но, если вы действительно хотите добавить целое число МС, МКС, или nsec к DispatchTime, вы также можете добавить DispatchTimeInterval до 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

Swift 4:

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

времени .seconds(Int), .microseconds(Int) и .nanoseconds(Int) может также использоваться.


Если вы просто хотите функцию задержки в

Swift 4

func delay(delay: Double, closure: @escaping () -> ()) {

     DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
          closure()
     }
}

Вы можете использовать его как:

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

после выпуска Swift 3 также должен быть добавлен @escaping

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

Swift 4

вы можете создать расширение на DispatchQueue и добавить функцию задержки, которая использует DispatchQueue функция asyncAfter внутренне

extension DispatchQueue {
   static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
      DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
   }
}

и использовать

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}

несколько иной вкус принятого ответа.

Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) + 
.microseconds(500) + .nanoseconds(1000)) {
                print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds + 
                      1000 nanoseconds)")
 }

вызов DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

Я настоятельно рекомендую использовать инструменты Xcode для преобразования в Swift 3 (Edit > Convert > to Current Swift Syntax). Он поймал это для меня


это сработало для меня в Swift 3

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds


DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    print("Sum of times: \(time1 + time2)")
}

можно использовать

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

попробуй такое

let when = DispatchTime.now() + 1.5
    DispatchQueue.main.asyncAfter(deadline: when) {
        //some code
    }

в Swift 4.1 и Xcode 9.4.1

простой ответ...

//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}