it-swarm.com.de

Wie schreibe ich dispatch_after GCD in Swift 3 und 4?

In Swift 2 konnte ich dispatch_after verwenden, um eine Aktion mit Grand Central Dispatch zu verzögern:

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

Dies scheint jedoch nicht mehr in Swift 3 (oder 4) zu kompilieren. Was ist die bevorzugte Methode, um dies in Swift 3 zu schreiben (unter Verwendung der neuen Dispatch-API)?

392
brandonscript

Die Syntax lautet einfach:

// to run something in 0.1 seconds

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

Die obige Syntax des Hinzufügens von seconds als Double scheint Verwirrung zu stiften (vor allem da wir es gewohnt waren, nsec hinzuzufügen). Die Syntax "addiere Sekunden als Double" funktioniert, da deadline ein DispatchTime ist und hinter den Kulissen ein +-Operator vorhanden ist, der einen Double benötigt und der DispatchTime diese vielen Sekunden hinzufügt

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

Wenn Sie jedoch wirklich eine Ganzzahl von ms, μs oder nsec zu DispatchTime hinzufügen möchten, können Sie auch DispatchTimeInterval zu DispatchTime hinzufügen. Das heißt, Sie können tun:

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

Alle funktionieren aufgrund dieser separaten Überladungsmethode nahtlos für den +-Operator in der DispatchTime-Klasse.

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

Swift 4:

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

Für die Zeit .seconds(Int) können auch .microseconds(Int) und .nanoseconds(Int) verwendet werden.

119

Wenn Sie nur die Verzögerungsfunktion wünschen

Swift 4

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

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

Sie können es wie folgt verwenden:

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

nach der Freigabe von Swift 3 muss auch das @escaping hinzugefügt werden

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

Swift 4

Sie können eine Erweiterung in DispatchQueue erstellen und eine Funktionsverzögerung hinzufügen, die intern die DispatchQueue asyncAfter-Funktion verwendet

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

und verwenden 

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

Eine etwas andere Variante der akzeptierten Antwort.

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

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

Ich würde dringend empfehlen, die Xcode-Tools zur Konvertierung nach Swift 3 zu verwenden (Bearbeiten> Konvertieren> In aktuelle Swift-Syntax). Es hat das für mich erwischt 

3
jjatie

Swift 5 und höher

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
   // code to execute                 
})
1
midhun p

In Swift 4.1 und Xcode 9.4.1

Einfache Antwort ist ...

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

Sie können verwenden

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

versuche dies

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

Das hat in Swift 3 für mich funktioniert

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
Ankit garg

Keine der genannten Antworten läuft auf einem Nicht-Haupt-Thread, also meine 2 Cent. 

In Hauptwarteschlange (Hauptthread) 

let mainQueue = DispatchQueue.main
let deadline = DispatchTime.now() + .seconds(10)
mainQueue.asyncAfter(deadline: deadline) {
    // ...
}

OR

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(10)) { 
    // ...
}

On globale Warteschlange (kein Hauptthread, basierend auf angegebenem QOS). 

let backgroundQueue = DispatchQueue.global()
let deadline = DispatchTime.now() + .milliseconds(100)
backgroundQueue.asyncAfter(deadline: deadline, qos: .background) { 
    // ...
}

OR

DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(100), qos: .background) {
    // ...
}
0
MANN