https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2

jest to kontynuacja współbieżności w serii swift. Zobacz część 1 i część 2, aby zrozumieć podstawy

w tej części omówimy następujące tematy

  1. co to jest operacje i stany życia
  2. Utwórz blok , NSInvocationOperation i niestandardowe operacje do uruchamiania zadań asynchronicznych
  3. jak anulować operacje
  4. co to są kolejki operacji
  5. jak dodawać operacje w kolejkach operacji
  6. jak tworzyć zależności między operacjami
  7. zalety kolejek operacji w GCD
  8. implementacja grupy dyspozytorskiej przy użyciu kolejek operacji

operacje są obiektowy sposób hermetyzacji pracy, którą chcesz wykonać asynchronicznie. Operacje są przeznaczone do użycia w połączeniu z kolejką operacji lub samodzielnie

obiekt operacji jest instancją klasy Operation or NSOperation (w frameworku Foundation), której używasz do enkapsulacji pracy, którą chcesz wykonać w aplikacji.

sama klasa operacyjna jest abstrakcyjną klasą bazową, która musi być podklasowana, aby wykonać jakąkolwiek użyteczną pracę. Pomimo bycia abstrakcyjnym, klasa ta zapewnia znaczną ilość infrastruktury, aby zminimalizować ilość pracy, którą musisz wykonać we własnych podklasach. Ponadto Framework Foundation zapewnia dwie konkretne podklasy, które można używać w stanie, w jakim jest z istniejącym kodem.

stan operacji

operacja ma maszynę stanową, która reprezentuje jej cykl życia. Istnieje kilka możliwych stanów, które występują w różnych częściach tego cyklu życia:

  • kiedy będzie instantiated, przejdzie do stanu isReady.
  • kiedy wywołamy metodę start, przejdzie ona do stanu isExecuting.
  • gdy zadanie finished , przenosi się do isFinished
  • gdy zadanie jest w toku i wywołujesz cancel , następnie przejdzie do stanu isCancelled, zanim przejdzie do stanu isFinished

istnieją głównie trzy sposoby tworzenia operacji

BlockOperation (Concrete Class)

Klasa, której używasz jako-jest do jednoczesnego wykonywania jednego lub więcej obiektów blokowych. Ponieważ może wykonać więcej niż jeden blok, obiekt operacji blokowej działa za pomocą semantyki grupy; tylko wtedy, gdy wszystkie powiązane bloki zakończą wykonywanie, sama operacja zostanie uznana za zakończoną.. W block operation możesz skorzystać z zależności operacji, KVO, powiadomień i anulowania .

jak pokazano na rysunku 1 wykonaliśmy ten kod async, co oznacza, że powróci on natychmiast, ale zła wiadomość jest taka, że zablokuje główny wątek, ponieważ operation.start() został wywołany w głównym wątku

Obiekty operacji domyślnie wykonują w sposób synchroniczny — to znaczy wykonują swoje zadanie w wątku, który wywołuje ich metodę start.

Rysunek 1

co do cholery jest synchroniczny sposób i wykonać jeden lub więcej obiektów blokowych jednocześnie.

jak pokazano na rysunku 1.0.1 jak widać zadania / bloki dodane do samej operacji bloku wykonywanej jednocześnie, ale synchroniczny sposób uruchamiania bloku oznacza, że zablokował wątek, w którym uruchamia się w naszym przypadku jest to główny wątek

rysunek 1.0.1

jak pokazano na rysunku rysunek 1.0.2, ponieważ wywołujemy metodę start na innym wątku, zablokuje ona ten wątek

rysunek 1.0.2

jak pokazano na rysunku rysunek 1.0.3, możemy również dodać blok dopełnienia, który będzie wywoływany, gdy wszystkie równoległe bloki zostaną wykonane

rysunek 1.0.3

Uruchom operację bloku jednocześnie

, jak pokazano na rysunku 1.1 ponieważ wywołujemy metodę start() w wątku tła, wykona ona swoje zadanie w wątku. Jest fajny sposób, aby to zrobić za pomocą kolejki operacji i zobaczymy to później.

rysunek 1.1

NSInvocationOperation (klasa betonu)

Klasa, której używasz jako-jest do tworzenia obiektu operacji na podstawie obiektu i selektora z Twojej aplikacji.

w objective C możemy utworzyć NSInvocationOperation, gdy nie jest dostępna w Swift.

https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW6

3. Operacje niestandardowe

Podklasowanie Operation daje pełną kontrolę nad implementacją własnych operacji, w tym możliwość zmiany domyślnego sposobu wykonywania operacji i raportowania jej statusu.

jak pokazano na rysunku 2, stworzyliśmy własne operacje za pomocą podklasy it z klasy bazowej Operation i nadpisaliśmy jej metodę main. Podczas podklasowania umieszczasz swoje zadanie w metodzie main. Zaimplementowaliśmy niestandardową operację non concurrent i w tym przypadku zablokowaliśmy główny wątek

Rysunek 2

jeśli planujesz wykonywać operacje ręcznie i nadal chcesz, aby działały asynchronicznie, musisz podjąć odpowiednie działania, aby to zrobić. Można to zrobić poprzez zdefiniowanie obiektu operacji jako operacji równoległej.

jak pokazano na rysunku 3 wykonaliśmy następujące kroki, aby wykonać zadanie jednocześnie

  1. utworzona podklasa MyConcurrentQueue. Literówka: Nazwa powinna być MyConcurrentOperations
  2. wywołanie start() metoda wywoła main() metoda na wątku tła
  3. na głównej metodzie zdefiniowaliśmy nasze zadanie i jedną rzeczą do zapamiętania jest również cancel case
  4. przy wywołaniu cancel na niestandardowej operacji przejdzie do stanu isCancelled i złamie pętlę i jak pokazano na rysunku 3 wydrukuje tylko 39487 elementów

Rysunek 3

kolejki operacji

  1. kolejki operacji są na GCD o wysokim poziomie abstrakcji
  2. przy użyciu Kolejki operacji zobaczysz rzeczywistą moc operacji, zamiast samego uruchamiania operacji, dajesz ją do kolejki operacji, a następnie obsługujesz planowanie i wykonywanie.
  3. kolejki operacji są zorientowanym obiektowo sposobem hermetyzacji pracy, którą chcesz wykonać asynchronicznie.
  4. dodajesz operations (zadania / praca) na operation queue i omówiliśmy, jak możemy tworzyć operacje przy użyciu dwóch metod.

Dodaj operacje

jak pokazano na rysunku 4 utworzyliśmy dwie operacje (używając bloku) i dodaliśmy je do kolejki operacji. Kolejka operacji uruchomiła obie operacje na jakimś wątku w tle i wykonała je. Nie ma potrzeby wywoływania metody start() w niestandardowym wątku 🆒. Gdy dodamy operację do kolejki operacji, uruchamia się, gdy tylko będzie gotowa

Rysunek 4

jak pokazano na rysunku 5 właśnie wykonaliśmy zadanie seryjnie lub możesz powiedzieć, że zaimplementowaliśmy kolejkę szeregową za pomocą kolejek operacyjnych, zapoznaj się z moją częścią 1, jeśli nie wiesz, co to jest kolejka szeregowa, ustawiając maxConcurrentOperationCount = 1

maxConcurrentOperationCount →Maksymalna liczba kolejkowanych operacji, które można wykonać w tym samym czasie. Wartością domyślną jest -1, co oznacza, że system decyduje

Rysunek 5

ustawiając maxConcurrentOperationCount = 2 utworzyliśmy równoległą kolejkę i teraz zadania są wykonywane jednocześnie, jak pokazano na rysunku 6

Rysunek 6

zależności operacji

jak pokazano na rysunku 7 ponownie stworzyliśmy kolejkę szeregową, dodając zależności między dwoma zadaniami. Utworzyliśmy dwie operacje blokowe i mówimy, że nie rozpoczynaj zadania 1, dopóki zadanie 2 nie zostanie zakończone przez wywołanie blockOperations1.addDependency(blockOperations2)

Rysunek 7

implementacja grupy Dyspozytorskiej za pomocą kolejki operacji

w części 2 użyliśmy funkcji grupy dyspozytorskiej GCD, aby zablokować wątek do czasu zakończenia wykonywania jednego lub więcej zadań. Jak pokazano na rysunku 8 zaimplementowaliśmy to samo zachowanie przy użyciu kolejek operacji za pomocą zależności. Jest to bardzo pomocne, jeśli nie możesz robić postępów, dopóki wszystkie określone zadania nie zostaną ukończone.

jak pokazano na rysunku 8 mamy trzy zadania i chcieliśmy działać jednocześnie, A gdy wszystkie zadania się skończyły, musimy wywołać jakąś metodę, aby wskazać, że wszystkie zadania się skończyły i to, co zrobiliśmy

  1. utworzyliśmy kolejkę operacji
  2. utworzyliśmy trzy operacje bloku, które wykonają zadania
  3. utworzy operację bloku zakończenia (blockOperations4), która uruchomi się, gdy wszystkie trzy zadania zostaną zakończone
  4. >
  5. made blockOperations4 dependent on blockOperations1, blockOperations2 and blockOperations3 co oznacza, że blockoperations4 wykona się po zakończeniu wszystkich trzech zadań
  6. waitUntilFinished → Blokuje wykonywanie bieżącego wątku, dopóki obiekt operation nie zakończy swojego zadania, ponieważ nie chcemy blokować bieżącego wątku, który jest główny, przypisujemy mu false
  7. Uruchom ten kod, a „cała operacja zostanie zakończona” wyświetli się po zakończeniu task1, task2 i task3

Rysunek 8

jak pokazano na rysunku 9, po prostu blokujemy główny wątek, ustawiając waitUntilFinished = true. , więc pytanie brzmi, kiedy jest to pomocne, a odpowiedź otrzymasz w następnej sekcji

Rysunek 9

jak pokazano na rysunku 10 zaimplementowaliśmy zachowanie grupy dyspozytorskiej przy użyciu kolejki operacji bez użycia żadnych zależności co zrobiliśmy użyliśmy odpowiednio funkcji waitUntilFinished . Jeśli jesteś na wątku w tle, możesz zablokować ten wątek, aby osiągnąć to zachowanie. Celowo przełączyłem się na wątek w tle za pomocą metody DispatchQueue.global().async patrz część 1, aby zrozumieć ten kod

powiedzieliśmy kolejce operacji uruchom zadanie 1, Zadanie 2 i Zadanie 3 w kolejce operacji i Zablokuj bieżący wątek, dopóki te równoległe zadania nie zakończą ich wykonania

Rysunek 10

korzyści z kolejek operacyjnych w GCD

  1. interfejs API operacji zapewnia obsługę zależności. Możesz tworzyć złożone zależności między zadaniami bardzo łatwo, chociaż w GCD możesz to osiągnąć, ale musisz wykonać dużo pracy.
  2. klasy NSOperation i NSOperationQueue mają szereg właściwości, które można zaobserwować za pomocą KVO (Key Value Observing). Jest to kolejna ważna korzyść, jeśli chcesz monitorować stan operacji lub kolejki operacji.
  3. operacje można wstrzymać, wznowić i anulować. Po wysłaniu zadania za pomocą Grand Central Dispatch nie masz już kontroli ani wglądu w jego wykonanie. API NSOperation jest bardziej elastyczne pod tym względem, dając deweloperowi kontrolę nad cyklem życia operacji
  4. NSOperationQueue dodaje również wiele korzyści do mieszanki. Na przykład można określić maksymalną liczbę kolejkowanych operacji, które mogą być uruchamiane jednocześnie. Ułatwia to kontrolowanie liczby operacji wykonywanych w tym samym czasie lub tworzenie szeregowej kolejki operacji.

nadchodzące

w następnej części przyjrzymy się rzeczywistemu Przypadkowi użycia tworzenia niestandardowej operacji

Przydatne linki

· https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW1

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.