Jak korzystać z wątków w trybie szybkim?
dispatchOnMainThread:^{
NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue()));
}];
ios
swift
multithreading
dispatch-queue
Anszul
źródło
źródło
]
przed średnikiem w ostatnim wierszu?DispatchQueue.global(qos: .background).async { print("Run on background thread") DispatchQueue.main.async { print("We finished that.") // only back on the main thread, may you access UI: label.text = "Done." } }
Odpowiedzi:
Swift 3.0+
Wiele zostało zmodernizowane w Swift 3.0. Uruchomienie czegoś w wątku w tle wygląda następująco:
Swift 1.2 do 2.3
Pre Swift 1.2 - Znany problem
Począwszy od Swift 1.1 Apple nie obsługiwał powyższej składni bez pewnych modyfikacji. Przekazywanie
QOS_CLASS_BACKGROUND
nie zadziałało, zamiast tego użyjInt(QOS_CLASS_BACKGROUND.value)
.Aby uzyskać więcej informacji, zobacz dokumentację jabłek
źródło
Async.background {}
Najlepszą praktyką jest zdefiniowanie funkcji wielokrotnego użytku, do której można uzyskać dostęp wielokrotnie.
FUNKCJA wielokrotnego użytku:
np. gdzieś jak AppDelegate.swift jako funkcja globalna.
Uwaga: w Swift 2.0 zastąpić QOS_CLASS_USER_INITIATED.value powyżej QOS_CLASS_USER_INITIATED.rawValue zamiast
STOSOWANIE:
A. Aby uruchomić proces w tle z opóźnieniem 3 sekund:
B. Aby uruchomić proces w tle, a następnie uruchom ukończenie na pierwszym planie:
C. Aby opóźnić o 3 sekundy - zwróć uwagę na użycie parametru zakończenia bez parametru tła:
źródło
if(background != nil){ background!(); }
zbackground?()
na nieco swiftier składni?DispatchQueue.global(priority: Int(DispatchQoS.QoSClass.userInitiated.rawValue)).async {
ale generuje to błąd podobny docannot invoke initializer for type 'Int' with an argument list of type '(qos_class_t)'
. Działające rozwiązanie znajduje się tutaj (DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated).async
).Odpowiedź Dana Beaulieu w swift5 (działa również od wersji 3.0.1).
Swift 5.0.1
Stosowanie
źródło
background
zamknięciu jest bardzo, bardzo, bardzo długa (~ = nieskończona). Ta metoda ma trwać przez określony czas: czas potrzebny na wykonanie zadania w tle. Tak więccompletion
zamknięcie zostanie wywołane, gdy minie czas wykonania zadania w tle + opóźnienie.Wersja Swift 3
Swift 3 wykorzystuje nową
DispatchQueue
klasę do zarządzania kolejkami i wątkami. Aby uruchomić coś w wątku w tle, użyj:Lub jeśli chcesz coś w dwóch wierszach kodu:
Możesz także uzyskać szczegółowe informacje o GDC w Swift 3 w tym samouczku .
źródło
Z samouczka Jamesona Quave'a
Swift 2
źródło
W Swift 4.2 i Xcode 10.1
Mamy trzy typy kolejek:
1. Kolejka główna: kolejka główna to kolejka szeregowa, która jest tworzona przez system i powiązana z głównym wątkiem aplikacji.
2. Globalna kolejka: globalna kolejka to współbieżna kolejka, którą możemy zażądać w odniesieniu do priorytetu zadań.
3. Kolejki niestandardowe: może tworzyć użytkownik. Niestandardowe współbieżne kolejki zawsze są mapowane na jedną z globalnych kolejek poprzez określenie właściwości Quality of Service (QoS).
Te wszystkie kolejki można wykonać na dwa sposoby
1. Synchroniczne wykonanie
2. Wykonanie asynchroniczne
Od AppCoda: https://www.appcoda.com/grand-central-dispatch/
źródło
.background
QoS,.userInitiated
ale dla mnie to zadziałało.background
Swift 4.x
Umieść to w jakimś pliku:
i nazwij to tam, gdzie potrzebujesz:
źródło
Musisz oddzielić zmiany, które chcesz uruchomić w tle, od aktualizacji, które chcesz uruchomić w interfejsie użytkownika:
źródło
dispatch_async(dispatch_get_main_queue()) { // update some UI }
się nazywa, gdy instrukcja w tle (blok zewnętrzny) jest wykonywana?Dobre odpowiedzi, w każdym razie chcę udostępnić moje rozwiązanie zorientowane obiektowo na bieżąco dla szybkiego 5 .
sprawdź to: AsyncTask
Zainspirowany koncepcyjnie Androidem AsyncTask, napisałem własną klasę w Swift
AsyncTask umożliwia prawidłowe i łatwe korzystanie z wątku interfejsu użytkownika. Ta klasa umożliwia wykonywanie operacji w tle i publikowanie wyników w wątku interfejsu użytkownika.
Oto kilka przykładów użycia
Przykład 1 -
Przykład 2 -
Ma 2 rodzaje ogólne:
BGParam
- typ parametru wysyłanego do zadania po wykonaniu.BGResult
- rodzaj wyniku obliczeń w tle.Podczas tworzenia zadania AsyncTask możesz przypisać te typy do wszystkiego, co potrzebujesz przekazać i wyjść z zadania w tle, ale jeśli nie potrzebujesz tych typów, możesz oznaczyć je jako nieużywane, ustawiając je na:
Void
lub krótszą składnią:()
Po wykonaniu zadania asynchronicznego przechodzi on przez 3 kroki:
beforeTask:()->Void
wywoływane w wątku interfejsu użytkownika tuż przed wykonaniem zadania.backgroundTask: (param:BGParam)->BGResult
wywoływane w wątku tła natychmiast poafterTask:(param:BGResult)->Void
wywoływane w wątku interfejsu użytkownika z wynikiem z zadania w tleźródło
Ponieważ odpowiedź na pytanie OP została już udzielona powyżej, chciałbym dodać kilka uwag dotyczących prędkości:
Nie polecam uruchamiania zadań z priorytetem wątku .background, szczególnie na iPhonie X, gdzie zadanie wydaje się być przydzielone do rdzeni o niskiej mocy.
Oto kilka rzeczywistych danych z funkcji intensywnie obliczeniowej, która czyta z pliku XML (z buforowaniem) i wykonuje interpolację danych:
Nazwa urządzenia / .background / .utility / .default / .userInitiated / .userInteractive
Pamiętaj, że zestaw danych nie jest taki sam dla wszystkich urządzeń. Jest to największy na iPhone X i najmniejszy na iPhone 5s.
źródło
Szybki 5
Aby to ułatwić, utwórz plik „DispatchQueue + Extensions.swift” z tą zawartością:
Stosowanie :
źródło
Grand Central Dispatch służy do obsługi wielozadaniowości w naszych aplikacjach na iOS.
Możesz użyć tego kodu
Więcej informacji za pomocą tego linku: https://www.programminghub.us/2018/07/integrate-dispatcher-in-swift.html
źródło
Funkcja wielofunkcyjna dla gwintu
Używaj go jak:
źródło
Naprawdę podoba mi się odpowiedź Dana Beaulieu, ale nie działa ona w Swift 2.2 i myślę, że możemy uniknąć tych paskudnych wymuszonych operacji odwijania!
źródło
źródło
w Swift 4.2 to działa.
źródło