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

Detta är fortsättningen av samtidigheten i swift-serien. Se del 1 och del 2 för att förstå grunderna

i den här delen kommer vi att täcka följande ämnen

  1. Vad är operationer och det är livstillstånd
  2. skapa Block, NSInvocationOperation och anpassade operationer för att köra uppgifter async
  3. hur man avbryter operationer
  4. Vad är Operationsköer
  5. hur man avbryter operationer
  6. så här skapar du beroenden mellan operationer
  7. fördelar med operationsköer över GCD
  8. Dispatch group implementation med operationsköer

verksamheten är en objektorienterat sätt att inkapsla arbete som du vill utföra asynkront. Operationer är utformade för att användas antingen i samband med en operationskö eller av sig själva

ett operationsobjekt är en instans av klassen Operation or NSOperation (i Foundation framework) som du använder för att inkapsla arbete du vill att din applikation ska utföra.

Operationsklassen i sig är en abstrakt basklass som måste underklassas för att kunna göra något användbart arbete. Trots att den är abstrakt ger den här klassen en betydande mängd infrastruktur för att minimera mängden arbete du behöver göra i dina egna underklasser. Dessutom ger Foundation framework två konkreta underklasser som du kan använda som-är med din befintliga kod.

Operations State

en operation har en tillståndsmaskin som representerar dess livscykel. Det finns flera möjliga tillstånd som uppstår vid olika delar av denna livscykel:

  • när det har varit instantiated kommer det att övergå till isReady – tillståndet.
  • när vi åberopade metoden start kommer den att övergå till tillståndet isExecuting.
  • när uppgiften finished flyttar den till isFinished
  • när uppgiften pågår och du ringer cancel, kommer den att övergå till tillståndet isCancelled innan du flyttar till tillståndet isFinished

det finns huvudsakligen tre sätt att skapa operationer

BlockOperation (betongklass)

en klass som du använder som-är att köra ett eller flera blockobjekt samtidigt. Eftersom det kan köra mer än ett block, fungerar ett blockoperationsobjekt med en gruppsemantisk; först när alla tillhörande block har slutförts anses själva operationen vara klar.. I blockdrift kan du dra nytta av driftsberoenden, KVO, aviseringar och annullering .

som visas i Figur 1 körde vi den här koden async vilket betyder att den kommer att återvända omedelbart men den dåliga nyheten är att den kommer att blockera huvudtråden eftersom operation.start() anropades på huvudtråden

Operationsobjekt körs på ett synkront sätt som standard — det vill säga de utför sin uppgift i tråden som kallar deras start – metod.

Figur 1

vad sjutton är synkront sätt och köra en eller flera blockobjekt samtidigt.

som visas i Figur 1.0.1 som du kan se de uppgifter / block som läggs till i själva blockoperationen utförs samtidigt men blockkörningen synkron sätt betyder att den blockerade tråden vid vilken start kallas i vårt fall är det huvudtråd

figur 1.0.1

som visas i Figur figur 1.0.2, eftersom vi kallar startmetod på annan tråd, kommer den att blockera den tråden

figur 1.0.2

som visas i Figur figur 1.0.3 kan vi också lägga till kompletteringsblock som kommer att ringa när alla samtidiga block kommer att utföras

figur 1.0.3

kör Blockoperation samtidigt

som visas i Figur 1.1 eftersom vi kallar start() metod på en bakgrundstråd kommer den att utföra sin uppgift i tråden. Det finns ett coolt sätt att göra detta med operation queue och vi kommer att se detta senare.

figur 1.1

NSInvocationOperation (betong klass)

en klass som du använder som-är att skapa en operation objekt baserat på ett objekt och väljare från din ansökan.

i mål C kan vi skapa NSInvocationOperation medan det inte är tillgängligt i Swift.

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

3. Anpassade operationer

Subclassing Operation ger dig fullständig kontroll över genomförandet av dina egna operationer, inklusive möjligheten att ändra standard sätt på vilket din operation utför och rapporterar dess status.

som visas i Figur 2 skapade vi anpassade operationer genom underklass den från Operation basklass och åsidosätter dess main – metod. När du underklass du sätter din uppgift på main metod. Vi genomförde icke-samtidig Anpassad operation och i det här fallet blockerade vi huvudtråden

Figur 2

om du planerar att utföra operationer manuellt och ändå vill att de ska köras asynkront måste du vidta lämpliga åtgärder för att säkerställa att de gör det. Du gör detta genom att definiera ditt operationsobjekt som en samtidig operation.

som visas i Figur 3 utförde vi följande steg för att utföra uppgift samtidigt

  1. skapad underklass MyConcurrentQueue. Skrivfel: Namnet ska vara MyConcurrentOperations
  2. ringa start() metod kommer att ringa main() metod på bakgrundstråd
  3. på huvudmetoden definierade vi vår uppgift och en sak att notera Vi tillgodoser Avbryt fall också
  4. vid samtal cancel vid Anpassad operation övergår till isCancelled staten och bryter slingan och som visas i Figur 3 kommer det att skriva ut endast 39487 objekt

Figur 3

Operationsköer

  1. Operations köer är Cocoa hög nivå abstraktion på GCD
  2. använda Operationsköer du kommer att se den verkliga kraften i operationer, istället för att starta operationen själv, ger du den till operationskön och hanterar sedan schemaläggning och körning.
  3. Operationsköer är ett objektorienterat sätt att inkapsla arbete som du vill utföra asynkront.
  4. du lägger till operations (uppgifter/arbete) på operation queue och vi diskuterade hur vi kan skapa operationer med två metoder.

Lägg till operationer

som visas i Figur 4 skapade vi två operationer (med Block) och lade till dem i operationskö. Operationskön startade båda operationerna på någon bakgrundstråd och körde dem. Inget behov av att ringa start() – metoden på Anpassad tråd bisexuell. När vi lägger till operation i operationskön körs den så snart den är klar

Figur 4

som visas i Figur 5 Vi utförde bara uppgiften seriellt eller så kan du säga att vi implementerade seriell kö med hjälp av Operationsköer, se min del 1 Om du inte vet vad som är seriell kö genom att ställa in maxConcurrentOperationCount = 1

maxConcurrentOperationCount →det maximala antalet köade operationer som kan utföras samtidigt. Standardvärdet är -1 vilket betyder att systemet bestämmer

Figur 5

genom att ställa in maxConcurrentOperationCount = 2 gjorde vi en samtidig kö och nu utförs uppgifter samtidigt som visas i Figur 6

Figur 6

Driftsberoenden

som visas i Figur 7 skapade vi igen en seriell kö genom att lägga till beroenden mellan två uppgifter. Vi skapade två blockoperationer och vi säger att starta inte Uppgift 1 tills Uppgift 2 är klar genom att ringa blockOperations1.addDependency(blockOperations2)

Figur 7

Dispatch Group implementering med Operations Queue

i del 2 använde vi GCD dispatch group-funktionen för att blockera en tråd tills en eller flera uppgifter slutfördes. Som visas i Figur 8 implementerade vi samma beteende med hjälp av Operationsköer genom att använda beroenden. Detta är till stor hjälp om du inte kan göra framsteg förrän alla angivna uppgifter är slutförda.

som visas i Figur 8 har vi tre uppgifter och vi ville köra samtidigt och när alla uppgifter är färdiga måste vi ringa någon metod för att indikera att alla uppgifter är färdiga och vad vi gjorde

  1. skapade en operationskö
  2. skapade tre blockoperationer som kommer att utföra uppgifter
  3. skapade en slutförande blockoperation (blockOperations4) som kommer att utlösa när alla tre uppgifterna är färdiga
  4. made blockOperations4 beroende på blockOperations1, blockOperations2 och blockOperations3 vilket innebär att blockoperations4 kommer att utföras när alla tre uppgifterna är färdiga
  5. waitUntilFinished → Blockerar exekvering av den aktuella tråden tills operationsobjektet avslutar sin uppgift eftersom vi inte vill blockera den aktuella tråden som är huvud vi tilldelar den med false
  6. kör den här koden och ”all Operation är klar” kommer att skrivas ut när task1, task2 och task3 är klar

figur 8

som visas i Figur 9 blockerar vi bara huvudtråden genom att ställa in waitUntilFinished = true. så frågan är när det är till hjälp och du får svaret i nästa avsnitt

Figur 9

som visas i Figur 10 implementerade vi ett sändningsgruppsbeteende med operationskö utan att använda några beroenden vad vi gjorde vi använde waitUntilFinished – funktionen på lämpligt sätt . Om du är på bakgrundstråd kan du blockera den här tråden för att uppnå detta beteende. Jag bytte avsiktligt till bakgrundstråd med DispatchQueue.global().async – metoden se del 1 för att förstå denna kod

vi berättade operation queue run task 1, task 2 och task 3 på operation queue och blockera den aktuella tråden tills dessa samtidiga uppgifter kommer att slutföra deras körning

Figur 10

fördelar med Operationsköer över GCD

  1. Operation API ger stöd för beroenden. Du kan skapa komplexa beroenden mellan uppgifter mycket enkelt men i GCD kan du uppnå det men du måste göra mycket arbete.
  2. klasserna NSOperation och NSOperationQueue har ett antal egenskaper som kan observeras med hjälp av KVO (Key Value Observer). Detta är en annan viktig fördel om du vill övervaka tillståndet för en operation eller operationskö.
  3. operationer kan pausas, återupptas och avbrytas. När du skickar en uppgift med Grand Central Dispatch har du inte längre kontroll eller insikt i utförandet av den uppgiften. Nsoperation API är mer flexibelt i det avseendet, vilket ger utvecklaren kontroll över operationens livscykel
  4. NSOperationQueue lägger också till ett antal fördelar för mixen. Du kan till exempel ange det maximala antalet köoperationer som kan köras samtidigt. Detta gör det enkelt att styra hur många operationer som körs samtidigt eller att skapa en seriell operationskö.

kommande

i nästa del kommer vi att titta på det faktiska användningsfallet för att skapa anpassad operation

användbara länkar

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

Lämna ett svar

Din e-postadress kommer inte publiceras.