W Swift 2 mogłem użyć dispatch_after
do opóźnienia akcji za pomocą wielkiej centralnej wysyłki:
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 wydaje się, że nie kompiluje się już od Swift 3. Jaki jest preferowany sposób pisania tego we współczesnym Swift?
swift
swift4
grand-central-dispatch
swift5
brandonscript
źródło
źródło
UInt64
?Odpowiedzi:
Składnia jest po prostu:
Zauważ, że powyższa składnia dodawania
seconds
jako aDouble
wydaje się być źródłem nieporozumień (szczególnie, że byliśmy przyzwyczajeni do dodawania nsec). TaDouble
składnia „dodaj sekundy jako ” działa, ponieważdeadline
jestDispatchTime
a, za kulisami istnieje+
operator, który zajmieDouble
i doda tyle sekund doDispatchTime
:Ale jeśli naprawdę chcesz dodać liczbę całkowitą msec, μs lub nsec do
DispatchTime
, możesz również dodać aDispatchTimeInterval
doDispatchTime
. Oznacza to, że możesz:Wszystko to działa bezproblemowo dzięki oddzielnej metodzie przeciążenia dla
+
operatora wDispatchTime
klasie.Zapytano, jak można anulować wysłane zadanie. Aby to zrobić, użyj
DispatchWorkItem
. Na przykład uruchamia to zadanie, które zostanie uruchomione za pięć sekund, lub jeśli kontroler widoku zostanie zwolniony i cofnięty,deinit
anuluje zadanie:Zwróć uwagę na użycie
[weak self]
listy przechwytywania wDispatchWorkItem
. Jest to niezbędne, aby uniknąć silnego cyklu odniesienia. Zauważ również, że nie powoduje to zapobiegawczego anulowania, ale po prostu zatrzymuje uruchamianie zadania, jeśli jeszcze tego nie zrobiło. Ale jeśli już się zaczął, zanim napotkacancel()
wywołanie, blok zakończy wykonywanie (chyba że ręcznie sprawdzaszisCancelled
wewnątrz bloku).źródło
DispatchTimeInterval
interpretacje, jak.milliseconds
wymagająInt
. Ale jeśli dodam tylko sekundy, użyłbymDouble
nplet n: Double = 1.0; queue.asyncAfter(deadline: .now() + n) { ... }
.Swift 4:
Do czasu
.seconds(Int)
,.microseconds(Int)
a.nanoseconds(Int)
może być również używany.źródło
.milliseconds
jest lepszy niż Double.DispatchTimeInterval
wartości wyliczenia.case seconds(Int)
case milliseconds(Int)
case microseconds(Int)
case nanoseconds(Int)
.milliseconds is better than Double.
- Chcę to na koszulce;).Jeśli chcesz tylko włączyć funkcję opóźnienia
Swift 4 i 5
Możesz go używać w następujący sposób:
źródło
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: closure)
jest prostsze.po wydaniu Swift 3 należy również dodać @escaping
źródło
Nieco inny smak odpowiedzi zaakceptowanej.
Szybki 4
źródło
Szybki 4
Możesz utworzyć rozszerzenie na DispatchQueue i dodać opóźnienie funkcji, które
DispatchQueue
wewnętrznie używa funkcji asyncAfterI użyć
źródło
połączenie
DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)
Zdecydowanie polecam użycie narzędzi Xcode do konwersji na Swift 3 (Edycja> Konwertuj> Na bieżącą składnię Swift). Złapało to dla mnie
źródło
W Swift 4.1 i Xcode 9.4.1
Prosta odpowiedź to ...
źródło
Swift 5 i wyżej
źródło
Żadna z wymienionych odpowiedzi nie działa w wątku innym niż główny, więc dodanie moich 2 centów.
W głównej kolejce (główny wątek)
LUB
W kolejce globalnej (nie główny wątek, na podstawie podanego QOS)
LUB
źródło
To działało dla mnie w Swift 3
źródło
Możesz użyć
źródło
Spróbuj tego
źródło