Przeglądałem iBook od Apple i nie mogę znaleźć żadnej jego definicji:
Czy ktoś może wyjaśnić strukturę dispatch_after
?
dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)
objective-c
swift
grand-central-dispatch
Kumar KL
źródło
źródło
Odpowiedzi:
Bardziej przejrzysty pomysł struktury:
dispatch_time_t
jestUInt64
. Wdispatch_queue_t
rzeczywistości jest to typ aliasu naNSObject
, ale powinieneś po prostu użyć znanych metod GCD, aby uzyskać kolejki. Blok jest szybkim zamknięciem. W szczególnościdispatch_block_t
jest zdefiniowany jako() -> Void
, co jest równoważne z() -> ()
.Przykładowe użycie:
EDYTOWAĆ:
Polecam użycie naprawdę fajnej
delay
funkcji @ matt .EDYCJA 2:
W Swift 3 pojawią się nowe opakowania dla GCD. Zobacz tutaj: https://github.com/apple/swift-evolution/blob/master/propozycje/0088-libdispatch-for-swift3.md
Oryginalny przykład zapisano by w Swift 3 w następujący sposób:
Pamiętaj, że możesz napisać
deadlineTime
deklarację jakoDispatchTime.now() + 1.0
i uzyskać ten sam wynik, ponieważ+
operator jest zastępowany w następujący sposób (podobnie dla-
):func +(time: DispatchTime, seconds: Double) -> DispatchTime
func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime
Oznacza to, że jeśli nie użyjesz
DispatchTimeInterval
enum
i po prostu napiszesz liczbę, zakłada się, że używasz sekund.źródło
dispatch_after(1, dispatch_get_main_queue()) { println("test") }
1
indispatch_after(1, ...
może spowodować wiele zamieszania tutaj. Ludzie pomyślą, że to liczba sekund, kiedy w rzeczywistości jest to nano-sekunda . Sugeruję, aby zobaczyć odpowiedź @brindy na temat prawidłowego tworzenia tego numeru.1
na,dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
ponieważ prowadzi to do zamieszania. Ludzie mogą pomyśleć, że nie musisz tworzyć dispatch_time_t w SwiftBinary operator '+' cannot be applied to operands of type DispatchTime and '_'
na liniilet delayTime = DispatchTime.now() + .seconds(1.0)
DispatchTime.now() + 1.0
wydaje się być jedynym sposobem, aby zadziałało (nie ma takiej potrzeby.seconds
)Używam
dispatch_after
tak często, że napisałem funkcję narzędzia najwyższego poziomu, aby uprościć składnię:A teraz możesz tak mówić:
Wow, język, w którym możesz poprawić język. Co mogło być lepiej?
Aktualizacja dla Swift 3, Xcode 8 Seed 6
Wydaje się, że prawie nie warto się tym przejmować, ponieważ poprawili składnię wywoływania:
źródło
func delayInSec(delay: Double) -> dispatch_time_t { return dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) }
return
.).1.0 ~~ { code...}
Swift 3+
Jest to bardzo łatwe i eleganckie w Swift 3+:
Starsza odpowiedź:
Aby rozwinąć odpowiedź Cezarego, która zostanie wykonana po 1 nanosekundie, musiałem wykonać następujące czynności, aby wykonać po 4 i pół sekundy.
Edycja: Odkryłem, że mój oryginalny kod był nieco niepoprawny. Wpisywanie niejawne powoduje błąd kompilacji, jeśli nie rzutujesz NSEC_PER_SEC na Double.
Jeśli ktoś może zaproponować bardziej optymalne rozwiązanie, chętnie to usłyszę.
źródło
dispatch_get_current_queue()
. Użyłemdispatch_get_main_queue()
zamiast tego.dispatch_get_main_queue()
to zdecydowanie to, czego powinieneś używać. Zaktualizuję.Składnia Matta jest bardzo ładna i jeśli musisz unieważnić blok, możesz użyć tego:
Użyj jak poniżej
kredyty
Powyższy link wydaje się nie działać. Oryginalny kod Objc z Github
źródło
performSelector:afterDelay:
jest teraz dostępna w Swift 2, więc możesz ją anulować.dispatch_source_t
z możliwością anulowania (używając a , ponieważ można to anulować).Najprostsze rozwiązanie w Swift 3.0 i Swift 4.0 i Swift 5.0
Stosowanie
źródło
Apple ma fragment dispatch_after dla celu C :
Oto ten sam fragment przeniesiony do Swift 3:
źródło
Innym sposobem jest rozszerzenie Double w ten sposób:
Następnie możesz użyć tego w następujący sposób:
Lubię funkcję opóźniającą Matta, ale po prostu wolę ograniczyć przekazywanie zamknięć.
źródło
W Swift 3.0
Wysyłaj kolejki
Wysyłaj po 5 sekundach
źródło
Wersja Swift 3.0
Po zamknięciu funkcji wykonaj pewne zadanie po opóźnieniu w głównym wątku.
Wywołaj tę funkcję jak:
źródło
1) Dodaj tę metodę jako część rozszerzenia UIViewController.
Wywołaj tę metodę na VC:
2)
3)
// Zwarta forma
źródło
Chociaż nie jest to pierwotne pytanie PO, niektóre
NSTimer
powiązane pytania zostały oznaczone jako duplikaty tego pytania, dlatego wartoNSTimer
tu podać odpowiedź.NSTimer
vsdispatch_after
NSTimer
jest wyższy poziom, podczas gdydispatch_after
jest bardziej niski poziom.NSTimer
łatwiej jest anulować. Anulowaniedispatch_after
wymaga napisania dodatkowego kodu .Opóźnianie zadania za pomocą
NSTimer
Utwórz
NSTimer
instancję.Uruchom stoper z potrzebnym opóźnieniem.
Dodaj funkcję, która ma być wywoływana po opóźnieniu (używając dowolnej nazwy użytej dla
selector
parametru powyżej).Notatki
timer.invalidate()
.repeats: true
.Jeśli masz zdarzenie jednorazowe bez potrzeby anulowania, nie ma potrzeby tworzenia
timer
zmiennej instancji. Wystarczą następujące elementy:Zobacz moją pełniejszą odpowiedź tutaj .
źródło
W przypadku wielu funkcji użyj tego. Jest to bardzo pomocne przy korzystaniu z animacji lub modułu ładującego działania dla funkcji statycznych lub dowolnej aktualizacji interfejsu użytkownika.
Na przykład - użyj animacji przed przeładowaniem tableView. Lub dowolna inna aktualizacja interfejsu użytkownika po animacji.
źródło
To zadziałało dla mnie.
Swift 3:
Cel C:
źródło
Swift 3 i 4:
Możesz utworzyć rozszerzenie w DispatchQueue i dodać opóźnienie funkcji, które wewnętrznie wykorzystuje funkcję asynchroniczną DispatchQueue
posługiwać się:
źródło
Kolejny pomocnik opóźniający twój kod, który jest w 100% szybki w użyciu i opcjonalnie pozwala wybrać inny wątek, aby uruchomić opóźniony kod z:
Teraz po prostu opóźniasz kod w głównym wątku w następujący sposób:
Jeśli chcesz opóźnić kod do innego wątku :
Jeśli wolisz Framework, który ma również kilka przydatnych funkcji, sprawdź HandySwift . Możesz dodać go do swojego projektu za pośrednictwem Kartaginy, a następnie użyć go dokładnie tak, jak w powyższych przykładach, np .:
źródło
Zawsze wolę używać rozszerzenia zamiast bezpłatnych funkcji.
Szybki 4
Użyj jak poniżej.
źródło
Opóźnianie połączenia GCD przy użyciu funkcji asynchronicznej po zakończeniu
Możemy opóźnić jako ** mikrosekundy , milisekundy , nanosekundy
źródło
W Swift 4
Użyj tego fragmentu:
źródło
dispatch_after(_:_:_:)
Funkcja przyjmuje trzy parametry:dispatch_after(_:_:_:)
Funkcja wywołuje blok lub zamknięcie w kolejce wysyłkowy, który jest przekazywany do funkcji po pewnym opóźnieniu. Zauważ, że opóźnienie jest tworzone za pomocądispatch_time(_:_:)
funkcji. Pamiętaj o tym, ponieważ używamy tej funkcji również w Swift.Polecam przejrzeć samouczek Samouczek Raywenderlich Dispatch
źródło
W Swift 5 użyj poniższych opcji:
źródło
użyj tego kodu do wykonania niektórych zadań związanych z interfejsem użytkownika po 2,0 sekundach.
Wersja Swift 3.0
Po zamknięciu funkcji wykonaj pewne zadanie po opóźnieniu w głównym wątku.
Wywołaj tę funkcję jak:
źródło
Teraz więcej niż cukier syntaktyczny do wysyłek asynchronicznych w Grand Central Dispatch (GCD) w Swift.
dodaj Podfile
Następnie możesz użyć tego w ten sposób.
źródło
Swift 4 ma dość krótki sposób:
źródło
Oto synchroniczna wersja asyncAfter w Swift:
Wraz z asynchronicznym:
źródło