Jak napisać dispatch po GCD w Swift 3 i 4?

W Swift 2 udało mi się użyć dispatch_after, aby opóźnić akcję za pomocą 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 
})

Ale to już nie wydaje się kompilować w Swift 3 (lub 4). Jaki jest preferowany sposób zapisu tego w Swift 3 (przy użyciu nowego API wysyłki)?

Author: brandonscript, 2016-06-14

11 answers

Składnia jest po prostu:

// to run something in 0.1 seconds

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

Uwaga, powyższa składnia dodawania seconds jako Double wydaje się być źródłem nieporozumień (esp, ponieważ byliśmy przyzwyczajeni do dodawania nsec). Ta składnia "dodaj sekundy jako Double" działa, ponieważ deadline jest DispatchTime, a za kulisami istnieje operator +, który zajmie Double i doda tyle sekund do DispatchTime:

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

Ale jeśli naprawdę chcesz dodać liczbę całkowitą msec, µs lub nsec do DispatchTime, Możesz również dodać DispatchTimeInterval do a DispatchTime. Oznacza to, że możesz zrobić:

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")
}

To wszystko bezproblemowo działa dzięki tej oddzielnej metodzie przeciążenia dla operatora + w klasie DispatchTime.

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
 912
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-14 20:42:34

Swift 4:

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

Na czas .seconds(Int), .microseconds(Int) i .nanoseconds(Int) mogą być również używane.

 105
Author: Hannes Sverrisson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 10:08:32

Jeśli chcesz tylko funkcję delay w

Swift 4

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

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

Możesz go używać w następujący sposób:

delay(delay: 1) { 
    print("Hi!")
}
 49
Author: rockdaswift,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-04 15:38:27

Po wydaniu Swift 3 należy dodać również @ escaping

func delay(_ delay: Double, closure: @escaping () -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
    closure()
  }
}
 15
Author: Marco Pappalardo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 15:40:39

Swift 4

Możesz utworzyć rozszerzenie na DispatchQueue i dodać funkcję delay, która używa DispatchQueue asyncafter wewnętrznie

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

I używać

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}
 5
Author: Suhit Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 09:32:47

Nieco inny smak zaakceptowanej odpowiedzi.

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)")
 }
 4
Author: Md. Ibrahim Hassan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 06:53:29

Call DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

Gorąco polecam korzystanie z narzędzi Xcode do konwersji do Swift 3 (Edycja > Konwertuj > do bieżącej składni Swift). It caught this for me

 3
Author: jjatie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 01:30:56

To działało dla mnie w 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)")
}
 0
Author: Ankit garg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-30 11:40:48

Możesz użyć

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) {
        // Code
    }
 0
Author: Parth Dhorda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 11:29:21

Spróbuj tego

let when = DispatchTime.now() + 1.5
    DispatchQueue.main.asyncAfter(deadline: when) {
        //some code
    }
 0
Author: A.Guz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 12:58:35

W Swift 4.1 i Xcode 9.4.1

Prosta odpowiedź brzmi...

//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
 0
Author: iOS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 06:11:29