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

aceasta este continuarea concurenței în seria swift. A se vedea partea 1 și partea 2 pentru a înțelege elementele de bază

în această parte vom acoperi următoarele subiecte

  1. ce este Operațiuni și este viață Statele
  2. crearea bloc, NSInvocationOperation , și operațiuni personalizate pentru a rula sarcini asincron
  3. cum de a anula operațiuni
  4. ce este cozile de Operare
  5. cum se adaugă operațiuni în cozile de operare
  6. cum se creează dependențe între operații
  7. beneficiile cozilor de operare peste GCD
  8. implementarea grupului de expediere utilizând cozile de operare

operațiunile sunt o mod orientat-obiect pentru a încapsula munca pe care doriți să efectuați asincron. Operațiunile sunt concepute pentru a fi utilizate fie împreună cu o coadă de operare, fie de la sine

un obiect de operare este o instanță a clasei Operation or NSOperation (în cadrul Fundației) pe care o utilizați pentru a încapsula munca pe care doriți ca aplicația dvs. să o efectueze.

clasa de Operare în sine este o clasă de bază abstractă care trebuie subclasată pentru a face orice lucrare utilă. În ciuda faptului că este abstract, această clasă oferă o cantitate semnificativă de infrastructură pentru a minimiza cantitatea de muncă pe care trebuie să o faceți în propriile subclase. În plus, cadrul Fundației oferă două subclase concrete pe care le puteți utiliza ca atare cu codul dvs. existent.

starea operațiunilor

o operațiune are o mașină de stare care reprezintă ciclul său de viață. Există mai multe stări posibile care apar în diferite părți ale acestui ciclu de viață:

  • când va fi instantiated , va trece la starea isReady.
  • când am invocat metoda start, aceasta va trece la starea isExecuting.
  • când sarcina finished, se mută la isFinished
  • atunci când sarcina este în curs de desfășurare și te sun cancel , atunci se va trece la isCancelled starea înainte de a trece pe isFinished starea

există în principal trei moduri de a crea operațiuni

BlockOperation (clasa de beton)

o clasă pe care o utilizați ca-este de a executa unul sau mai multe obiecte bloc simultan. Deoarece poate executa mai mult de un bloc, un obiect de operație bloc funcționează folosind un grup semantic; numai atunci când toate blocurile asociate au terminat de executat, operația în sine este considerată finalizată.. În funcționarea bloc puteți profita de dependențe de operare, KVO, notificări și anulare .

așa cum se arată în Figura 1 am executat acest cod asyncceea ce înseamnă că va reveni imediat, dar vestea proastă este că va bloca firul principal, deoarece operation.start() a fost apelat pe firul principal

obiectele de Operare execută în mod sincron în mod implicit — adică își îndeplinesc sarcina în firul care numește metoda start.

Figura 1

ce naiba este modul sincron și executa unul sau mai multe obiecte bloc simultan.

așa cum se arată în figura 1.0.1 după cum puteți vedea sarcinile / blocurile adăugate la operația blocului în sine executate simultan, dar modul sincron de rulare a blocului înseamnă că a blocat firul la care se numește start în cazul nostru este firul principal

figura 1.0.1

așa cum se arată în Figura Figura 1.0.2, din moment ce numim metoda de pornire pe alt fir , acesta va bloca acel fir

figura 1.0.2

așa cum se arată în Figura Figura 1.0.3, putem adăuga bloc de finalizare, de asemenea, care va apela atunci când toate blocurile concurente vor fi executate

figura 1.0.3

executați simultan funcționarea blocului

așa cum se arată în Figura 1.1 din moment ce numim start() metoda pe un fir de fundal se va efectua sarcina lor în firul. Există o modalitate interesantă de a face acest lucru folosind operation queue și vom vedea acest lucru mai târziu.

figura 1.1

NSInvocationOperation (clasa de beton)

o clasă pe care o utilizați ca-este de a crea un obiect de operare bazat pe un obiect și selector din aplicația dumneavoastră.

în obiectivul C putem crea NSInvocationOperation în timp ce nu este disponibil în Swift.

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

3. Operațiuni personalizate

subclasarea Operation vă oferă control complet asupra implementării propriilor operațiuni, inclusiv posibilitatea de a modifica modul implicit în care operațiunea dvs. execută și raportează starea acesteia.

așa cum se arată în Figura 2, am creat operații personalizate prin subclasarea acesteia din clasa de bază Operation și am înlocuit metoda main. Când subclasa ai pus sarcina pe main metodă. Am implementat operațiuni personalizate non concurente și în acest caz am blocat firul principal

Figura 2

Dacă intenționați să executați operațiunile manual și totuși doriți ca acestea să ruleze asincron, trebuie să luați măsurile corespunzătoare pentru a vă asigura că o fac. Faceți acest lucru definind obiectul operației dvs. ca o operație concurentă.

așa cum se arată în Figura 3, am efectuat următorii pași pentru a efectua sarcina concomitent

  1. subclasă creată MyConcurrentQueue. Typo: Numele ar trebui să fie MyConcurrentOperations
  2. apelarea start() metoda va apela main() metoda pe firul de fundal
  3. pe metoda principală am definit sarcina noastră și un lucru de reținut ne satisface anula caz, precum și
  4. la apelarea cancel pe operațiune personalizată va trece la isCancelled de stat și rupe bucla și așa cum se arată în Figura 3 se va imprima numai 39487 elemente

Figura 3

cozile de operații

  1. cozile de operații sunt abstractizarea la nivel înalt a Cocoa pe GCD
  2. folosind Cozile de operare veți vedea puterea reală a operațiunilor , în loc de a începe operațiunea le da la coada de operare se ocupa apoi programarea și executarea.
  3. cozile de operare sunt un mod orientat-obiect pentru a încapsula munca pe care doriți să efectuați asincron.
  4. adăugați operations (tasks/work) la operation queue și am discutat despre cum putem crea operații utilizând două metode.

adăugați operații

așa cum se arată în Figura 4 am creat două operații (folosind Block) și le-am adăugat în coadă de operare. Operațiunea Coadă a început atât operațiunea pe un fir de fundal și le-a executat. Nu este nevoie pentru a apela start() metoda de pe fir personalizat XV. Când adăugăm operație la coada de operare se execută de îndată ce este gata

Figura 4

așa cum se arată în Figura 5 tocmai am executat sarcina în serie sau puteți spune că am implementat coada serială folosind cozile de operare vă rugăm să consultați partea mea 1 dacă nu știți ce este coada serială setând maxConcurrentOperationCount = 1

maxConcurrentOperationCount →numărul maxim de operațiuni în coadă care pot fi executate în același timp. Valoarea implicită este -1 ceea ce înseamnă lăsați sistemul să decidă

Figura 5

prin setarea maxConcurrentOperationCount = 2 am făcut o coadă concurentă și acum sarcinile se execută simultan așa cum se arată în Figura 6

Figura 6

operațiuni dependențe

așa cum se arată în Figura 7 am creat din nou o coadă de serie prin adăugarea de dependențe între două sarcini. Am creat două operații bloc și noi spunem că nu începe sarcina 1 până când sarcina 2 este terminat de asteptare blockOperations1.addDependency(blockOperations2)

Figura 7

implementarea grupului de expediere utilizând coada de operații

în partea 2 am folosit caracteristica grupului de expediere GCD pentru a bloca un fir până când una sau mai multe sarcini au terminat executarea. Așa cum se arată în Figura 8 am implementat același comportament folosind cozile de operare folosind dependențe. Acest lucru este foarte util dacă nu puteți face progrese până când toate sarcinile specificate sunt finalizate.

așa cum se arată în Figura 8, avem trei sarcini și am vrut să rulăm simultan și când toate sarcinile s-au terminat, trebuie să apelăm la o metodă pentru a indica faptul că toate sarcinile s-au terminat și ceea ce am făcut

  1. a creat o coadă de operare
  2. a creat trei operații bloc care vor efectua sarcini
  3. a creat o operație bloc de finalizare (blockOperations4) care va declanșa când toate cele trei 800>
  4. made blockOperations4 dependente de blockOperations1, blockOperations2 și blockOperations3 ceea ce înseamnă blockoperations4 va executa atunci când toate cele trei sarcini va terminat
  5. waitUntilFinished → Blochează executarea firului curent până când obiectul de Operare își termină sarcina, deoarece nu dorim să blocăm firul curent, care este principal, îl atribuim cu fals
  6. rulați acest cod și „toată operațiunea este finalizată” se va imprima când task1, task2 și task3 se vor termina

figura 8

așa cum se arată în Figura 9, blocăm firul principal setând waitUntilFinished = true. deci întrebarea este când este util și veți primi răspunsul în secțiunea următoare

Figura 9

așa cum se arată în Figura 10 am implementat un comportament de grup de expediere folosind coadă de operare fără a utiliza dependențe ceea ce am făcut am folosit waitUntilFinished caracteristică în mod corespunzător . Dacă sunteți pe firul de fundal puteți bloca acest fir pentru a realiza acest comportament. Am trecut în mod intenționat la firul de fundal folosind metoda DispatchQueue.global().async vezi partea 1 pentru a înțelege acest cod

am spus operation queue run task 1, task 2 și task 3 pe operation queue și blocați firul curent până când aceste sarcini concurente își vor termina execuția

Figura 10

beneficiile cozilor de Operare peste GCD

  1. API-ul de operare oferă suport pentru dependențe. Puteți crea dependențe complexe între sarcini foarte ușor, deși în GCD îl puteți realiza, dar trebuie să faceți multă muncă.
  2. clasele NSOperation și NSOperationQueue au un număr de proprietăți care pot fi observate, folosind KVO (Key Value Observing). Acesta este un alt beneficiu important dacă doriți să monitorizați starea unei operații sau a unei cozi de operare.
  3. operațiunile pot fi întrerupte, reluate și anulate. Odată ce expediați o sarcină folosind Grand Central Dispatch, nu mai aveți control sau perspectivă asupra executării acelei sarcini. API-ul NSOperation este mai flexibil în acest sens, oferind dezvoltatorului controlul asupra ciclului de viață al operațiunii
  4. NSOperationQueue adaugă, de asemenea, o serie de beneficii mixului. De exemplu, puteți specifica numărul maxim de operații în coadă care pot rula simultan. Acest lucru face ușor să controlați câte operații rulează în același timp sau să creați o coadă de operații seriale.

viitoare

în partea următoare, ne vom uita la cazul de utilizare reală a crea operațiune personalizată

link-uri utile

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

Lasă un răspuns

Adresa ta de email nu va fi publicată.