Gibt es eine Möglichkeit, einen Block mit einem primitiven Parameter nach einer Verzögerung aufzurufen, z. B. performSelector:withObject:afterDelay:
mit einem Argument wie int
/ double
/ float
?
735
Gibt es eine Möglichkeit, einen Block mit einem primitiven Parameter nach einer Verzögerung aufzurufen, z. B. performSelector:withObject:afterDelay:
mit einem Argument wie int
/ double
/ float
?
Antworten:
Ich denke du suchst
dispatch_after()
. Es erfordert, dass Ihr Block keine Parameter akzeptiert, aber Sie können den Block stattdessen einfach diese Variablen aus Ihrem lokalen Bereich erfassen lassen.Weitere Informationen : https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
quelle
dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC)
Ausschnitt ist böse. Gibt es dafür keinen saubereren Weg?dispatch_get_current_queue()
immer die Warteschlange zurück, aus der der Code ausgeführt wird. Wenn dieser Code vom Hauptthread ausgeführt wird, wird der Block auch im Hauptthread ausgeführt.dispatch_get_current_queue()
ist jetzt veraltetSie können
dispatch_after
später einen Block aufrufen. Beginnen Sie in Xcode mit der Eingabedispatch_after
undEnter
drücken Sie, um die folgenden Schritte automatisch zu vervollständigen:Hier ist ein Beispiel mit zwei Gleitkommazahlen als "Argumente". Sie müssen sich nicht auf irgendeine Art von Makro verlassen, und die Absicht des Codes ist ganz klar:
Swift 3, Swift 4
Swift 2
Ziel c
quelle
NSEC_PER_SEC * 0.5
würde das genauso funktionieren wieNSEC_PER_MSEC * 500
. Während Sie zu Recht feststellen,dispatch_time
dass eine 64-Bit-Ganzzahl erwartet wird, wird der erwartete Wert in Nanosekunden angegeben.NSEC_PER_SEC
ist definiert als1000000000ull
und das Multiplizieren mit einer Gleitkommakonstante0.5
würde implizit eine Gleitkomma-Arithmetik ausführen, die sich ergibt500000000.0
, bevor sie explizit in eine 64-Bit-Ganzzahl zurückgesetzt wird. Es ist also durchaus akzeptabel, einen Bruchteil von zu verwendenNSEC_PER_SEC
.Wie wäre es mit der in Xcode integrierten Code-Snippet-Bibliothek?
Update für Swift:
Viele Stimmen haben mich dazu inspiriert, diese Antwort zu aktualisieren.
Die integrierte Xcode-Code-Snippet-Bibliothek ist
dispatch_after
nur für dieobjective-c
Sprache verfügbar . Benutzer können auch ihr eigenes benutzerdefiniertes Code-Snippet für erstellenSwift
.Schreiben Sie dies in Xcode.
Ziehen Sie diesen Code und legen Sie ihn im Bereich der Code-Snippet-Bibliothek ab.
Am Ende der Code-Snippet-Liste wird eine neue Entität mit dem Namen angezeigt
My Code Snippet
. Bearbeiten Sie dies für einen Titel. Für Vorschläge, während Sie den Xcode eingeben, füllen Sie das Feld ausCompletion Shortcut
.Weitere Informationen finden Sie unter Erstellen eines CustomCodeSnippets .
Aktualisieren Sie Swift 3
Ziehen Sie diesen Code und legen Sie ihn im Bereich der Code-Snippet-Bibliothek ab.
quelle
Als Erweiterung der Antwort von Jaime Cham habe ich eine NSObject + Blocks-Kategorie wie folgt erstellt. Ich war der Meinung, dass diese Methoden besser zu den vorhandenen
performSelector:
NSObject-Methoden passenNSObject + Blocks.h
NSObject + Blocks.m
und benutze so:
quelle
delay
sollte von seinNSTimeInterval
(was a istdouble
).#import <UIKit/UIKit.h>
wird nicht gebraucht. Und ich verstehe nicht, warum- (void)performBlock:(void (^)())block;
nützlich sein könnte, kann also aus dem Header entfernt werden.Vielleicht einfacher als GCD zu durchlaufen, in einer Klasse irgendwo (zB "Util") oder in einer Kategorie nach Objekt:
Also zu benutzen:
quelle
Für Swift habe ich mit dieser
dispatch_after
Methode eine globale Funktion erstellt, die nichts Besonderes ist . Ich mag das mehr, da es lesbar und einfach zu bedienen ist:Welche können Sie wie folgt verwenden:
quelle
after
. Dann können Sie schreiben:after(2.0){ print("do somthing") }
Hier sind meine 2 Cent = 5 Methoden;)
Ich mag es, diese Details zu kapseln und AppCode sagt mir, wie ich meine Sätze beenden soll.
quelle
PerformSelector: WithObject nimmt immer ein Objekt, um Argumente wie int / double / float usw. zu übergeben. Sie können so etwas verwenden.
// NSNumber ist ein Objekt ..
Auf die gleiche Weise können Sie [NSNumber numberWithInt:] etc .... verwenden und in der Empfangsmethode die Nummer in Ihr Format als [number int] oder [number double] konvertieren.
quelle
Die Funktion dispatch_after sendet nach einer bestimmten Zeit ein Blockobjekt an eine Versandwarteschlange. Verwenden Sie den folgenden Code, um nach 2,0 Sekunden einige UI-bezogene Takes durchzuführen.
In schnellem 3.0:
quelle
mainQueue,
anstelle vonmainQueue)
Hier ist die Swift 3-Methode, um die Arbeit nach einer Verzögerung in die Warteschlange zu stellen.
quelle
Hier ist ein praktischer Helfer , um zu verhindern, dass der nervige GCD immer wieder aufgerufen wird:
Jetzt verzögern Sie einfach Ihren Code im Haupt-Thread wie folgt:
Wenn Sie Ihren Code auf einen anderen Thread verschieben möchten :
Wenn Sie ein Framework bevorzugen , das auch einige weitere praktische Funktionen bietet, lesen Sie HandySwift . Sie können es über Karthago zu Ihrem Projekt hinzufügen und dann genau wie in den obigen Beispielen verwenden:
quelle
Es gibt eine schöne im BlocksKit-Framework.
BlocksKit
(und die Klasse)
BBlocksKit.m
quelle
In Swift 3 können wir einfach die Funktion DispatchQueue.main.asyncAfter verwenden, um eine Funktion oder Aktion nach der Verzögerung von 'n' Sekunden auszulösen. Hier im Code haben wir die Verzögerung nach 1 Sekunde eingestellt. Sie rufen jede Funktion im Hauptteil dieser Funktion auf, die nach einer Verzögerung von 1 Sekunde ausgelöst wird.
quelle
Xcode 10.2 und Swift 5 und höher
quelle
Sie können das Argument entweder in Ihre eigene Klasse einschließen oder den Methodenaufruf in eine Methode einschließen, die nicht im primitiven Typ übergeben werden muss. Rufen Sie diese Methode nach Ihrer Verzögerung auf und führen Sie innerhalb dieser Methode den Selektor aus, den Sie ausführen möchten.
quelle
So können Sie nach einer Verzögerung in Swift einen Block auslösen:
Es ist als Standardfunktion in meinem Repo enthalten .
quelle
Swift 3 & Xcode 8.3.2
Dieser Code wird Ihnen helfen, ich füge auch eine Erklärung hinzu
quelle
Ich glaube, der Autor fragt nicht, wie man auf einen Bruchteil der Zeit wartet (Verzögerung), sondern wie man einen Skalar als Argument des Selektors übergibt (withObject :) und der schnellste Weg im modernen Ziel C ist:
Ihr Selektor muss seinen Parameter in NSNumber ändern und den Wert mit einem Selektor wie floatValue oder doubleValue abrufen
quelle