585 Stimmen

Dispatch_after - GCD in Swift? dispatch_after - GCD in Swift?

Ich habe das iBook von Apple durchgesehen und konnte keine Definition davon finden:

Kann jemand die Struktur von dispatch_after erklären?

dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)

5voto

Suragch Punkte 420096

Auch wenn es nicht die originale Frage des OP war, wurden bestimmte mit NSTimer verwandte Fragen als Duplikate dieser Frage markiert, daher lohnt es sich, hier auch eine NSTimer Antwort einzuschließen.

NSTimer vs dispatch_after

  • NSTimer ist eher auf einer höheren Ebene, während dispatch_after eher auf einer niedrigen Ebene ist.
  • NSTimer ist einfacher abzubrechen. Das Abbrechen von dispatch_after erfordert das Schreiben von mehr Code.

Aufgabe mit Verzögerung mit NSTimer

Erstellen Sie eine NSTimer-Instanz.

var timer = NSTimer()

Starten Sie den Timer mit der benötigten Verzögerung.

// den Timer ungültig machen, wenn es eine Chance gibt, dass er zuvor aufgerufen wurde
timer.invalidate()
// Verzögerung von 2 Sekunden
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 

Fügen Sie eine Funktion hinzu, die nach der Verzögerung aufgerufen werden soll (verwenden Sie dabei den Namen, den Sie für den selector-Parameter oben verwendet haben).

func delayedAction() {
    print("Die verzögerte Aktion hat jetzt begonnen.")
}

Anmerkungen

  • Wenn Sie die Aktion vor Ausführung abbrechen müssen, rufen Sie einfach timer.invalidate() auf.

  • Für eine wiederholte Aktion verwenden Sie repeats: true.

  • Wenn Sie ein einmaliges Ereignis ohne Abbruchbedarf haben, müssen Sie keine timer-Instanzvariable erstellen. Das Folgende genügt:

    NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 
  • Lesen Sie meine ausführlichere Antwort hier.

5voto

Himanshu Mahajan Punkte 4603

Swift 3.0-Version

Nachfolgende Closure-Funktion führt einige Aufgaben nach einer Verzögerung im Hauptthread aus.

func performAfterDelay(delay: Double, onCompletion: @escaping() -> Void){

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
       onCompletion()
    })
}

Rufen Sie diese Funktion wie folgt auf:

performAfterDelay(delay: 4.0) {
  print("test")
}

3voto

Rahul Singha Roy Punkte 542

Für mehrere Funktionen verwenden Sie dies. Dies ist sehr hilfreich für die Verwendung von Animationen oder Aktivitätsladern für statische Funktionen oder jegliche UI-Aktualisierung.

DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
            // Rufen Sie Ihre Funktion 1 auf
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                // Rufen Sie Ihre Funktion 2 auf
            }
        }

Zum Beispiel - Verwenden Sie eine Animation, bevor eine TableView neu geladen wird. Oder irgendeine andere UI-Aktualisierung nach der Animation.

*// Starte deine Animation* 
self.startAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
                *// Die Animation wird je nach Verzögerungszeit ausgeführt*
                self.stopAnimation()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    *// Jetzt aktualisiere deine Ansicht*
                     self.fetchData()
                     self.updateUI()
                }
            }

2voto

garg Punkte 2455

Dies hat für mich funktioniert.

Swift 3:

let time1 = 8.23
let time2 = 3.42

// Verzögerung um 2 Sekunden

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    print("Summe der Zeiten: \(time1 + time2)")
}

Objective-C:

CGFloat time1 = 3.49;
CGFloat time2 = 8.13;

// Verzögerung um 2 Sekunden

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    CGFloat newTime = time1 + time2;
    NSLog(@"Neue Zeit: %f", newTime);
});

2voto

Suhit Patil Punkte 11098

Swift 3 & 4:

Sie können eine Erweiterung auf DispatchQueue erstellen und die Funktion delay hinzufügen, die intern die DispatchQueue asyncAfter Funktion verwendet

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

Verwendung:

DispatchQueue.delay(.seconds(1)) {
    print("Dies ist nach der Verzögerung")
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X