
Dit is de voortzetting van de concurrency in swift-serie. Zie deel1 en deel 2 te begrijpen van de basisprincipes
In dit deel behandelen we volgende onderwerpen
- Wat is de Operations en It ‘ s Life staten
- Maak Blokkeren, NSInvocationOperation , en Aangepaste Activiteiten om taken te kunnen uitvoeren async
- Hoe te annuleren activiteiten
- Wat is de Werking Wachtrijen
- het toevoegen van Activiteiten In Werking Wachtrijen
- het maken van afhankelijkheden tussen Activiteiten
- de Voordelen van de Operatie Wachtrijen Over GCD
- Verzending Groep Implementatie Met de Werking Wachtrijen
Operaties zijn een objectgeoriënteerde manier om werk te inkapselen dat u asynchroon wilt uitvoeren. Operaties zijn ontworpen om te worden gebruikt in combinatie met een operatie wachtrij of door zichzelf
een operatie object is een instantie van de Operation or NSOperation
klasse (in het Foundation framework) die u gebruikt om werk dat u wilt dat uw toepassing uit te voeren inkapselen.
de Operatieklasse zelf is een abstracte basisklasse die moet worden gesubclasseerd om enig nuttig werk te kunnen doen. Ondanks het feit dat abstract, deze klasse biedt een aanzienlijke hoeveelheid infrastructuur om de hoeveelheid werk die je moet doen in uw eigen subklassen te minimaliseren. Daarnaast biedt het Foundation framework twee concrete subklassen die je als-is kunt gebruiken met je bestaande code.
bedrijfstoestand
een bewerking heeft een toestandsmachine die de levenscyclus ervan weergeeft. Er zijn verschillende mogelijke toestanden die zich voordoen op verschillende delen van deze levenscyclus:
- als het
instantiated
is geweest, zal het overgaan naar deisReady
status. - wanneer we de
start
methode aanroepen, zal deze overgaan naar deisExecuting
status. - wanneer de taak
finished
wordt verplaatst naarisFinished
- wanneer de taak wordt uitgevoerd en u
cancel
aanroept, zal deze overgaan naar de statusisCancelled
voordat u naar de statusisFinished
gaat er zijn hoofdzakelijk drie manieren om bewerkingen
BlockOperation (Concrete Class)
een klasse die u gebruikt als-is om een of meer blokobjecten gelijktijdig uit te voeren. Omdat het meer dan één blok kan uitvoeren, werkt een blokbedieningsobject met behulp van een groepssemantisch; alleen als alle bijbehorende blokken klaar zijn met Uitvoeren wordt de operatie zelf als voltooid beschouwd.. In block operation kunt u profiteren van operatie afhankelijkheden, KVO, meldingen en annuleren.
zoals weergegeven in Figuur 1 hebben we deze code async
uitgevoerd, wat betekent dat het onmiddellijk zal terugkeren, maar het slechte nieuws is dat het de hoofdthread zal blokkeren omdat operation.start()
werd aangeroepen op hoofdthread
Operatieobjecten standaard synchroon uitvoeren — dat wil zeggen, ze voeren hun taak uit in de thread die hun
start
methode aanroept.

wat de heck is synchrone manier en een of meer blok objecten tegelijkertijd uit te voeren.
zoals weergegeven in Figuur 1.0.1 zoals u kunt zien de taken/blokken toegevoegd aan het blok operatie zelf gelijktijdig uitgevoerd, maar het blok run synchrone manier betekent dat het Geblokkeerd de thread bij welke start wordt genoemd in ons geval is het hoofd thread

Zoals weergegeven in figuur Figuur 1.0.2 , omdat we noemen start-methode op de andere thread , zal het blok in de thread

Zoals weergegeven in figuur Figuur 1.0.3, we kunnen toevoegen voltooiing blok en die wordt aangeroepen wanneer alle gelijktijdige blokken wordt uitgevoerd

Voer Blok Werking Gelijktijdig
Zoals getoond in Figuur 1.1 omdat we start()
methode op een achtergrond thread aanroepen, zal deze hun taak in de thread uitvoeren. Er is een coole manier om dit te doen met behulp van operation queue en we zullen dit later zien.

NSInvocationOperation (Betonklasse)
een klasse die u gebruikt als-is om een operatie-object te maken op basis van een object en een selector van uw toepassing.
in doelstelling C kunnen we NSInvocationOperation
aanmaken terwijl het niet beschikbaar is in Swift.

3. Aangepaste bewerkingen
Subclassing
Operation
geeft u volledige controle over de implementatie van uw eigen bewerkingen, inclusief de mogelijkheid om de standaard manier te veranderen waarop uw operatie wordt uitgevoerd en de status ervan rapporteert.
zoals weergegeven in Figuur 2 hebben we aangepaste bewerkingen gemaakt per subklasse van Operation
basisklasse en overschrijven de main
methode. Wanneer u subklasseert zet u uw taak op main
methode. We hebben niet-gelijktijdige aangepaste bewerking geïmplementeerd en in dit geval hebben we de hoofddraad geblokkeerd

Als u van plan bent om bewerkingen handmatig uit te voeren en nog steeds wilt dat ze asynchroon worden uitgevoerd, moet u de juiste acties ondernemen om ervoor te zorgen dat ze doen. U doet dit door uw operation object te definiëren als een gelijktijdige operatie.
zoals weergegeven in Figuur 3 hebben we de volgende stappen uitgevoerd om de taak tegelijkertijd uit te voeren
- aangemaakt subklasse
MyConcurrentQueue
. Typefout: De naam moet wordenMyConcurrentOperations
- Bellen
start()
methode wordt aangeroepen,main()
methode op de achtergrond draad - Op de belangrijkste methode die we gedefinieerd hebben onze taak en één ding om op te merken wij komen tegemoet te annuleren geval
- Op te bellen
cancel
op aangepaste bewerking zal de overgang naar deisCancelled
staat en de lus te onderbreken en zoals weergegeven in Figuur 3 het zal alleen printen 39487 items

Werking Wachtrijen
- Activiteiten Wachtrijen zijn Cacao hoog niveau van abstractie op GCD
- het Gebruik van Operation Queues u zult de echte kracht van operaties te zien, in plaats van het starten van de operatie zelf , je geeft het aan de operation queue het vervolgens behandelen van de planning en uitvoering.
- Operatiewachtrijen zijn een objectgeoriënteerde manier om werk dat u asynchroon wilt uitvoeren, in te kapselen.
- u voegt
operations
(taken / werk) toe aanoperation queue
en we bespraken hoe we bewerkingen kunnen maken met behulp van twee methoden.
bewerkingen
toevoegen zoals weergegeven in Figuur 4 hebben we twee bewerkingen gemaakt (met behulp van blok) en deze toegevoegd aan de bewerkingswachtrij. Operation queue startte beide bewerkingen op een aantal achtergrond thread en voerde ze uit. Het is niet nodig om start()
methode aan te roepen op aangepaste thread 🆒. Wanneer we toevoegen aan de werking wachtrij voor het uitvoeren zodra het klaar is

Zoals weergegeven in Figuur 5 hebben we een net uitgevoerde taak serieel of u kunt zeggen: wij hebben een seriële wachtrij met behulp van de Werking Wachtrijen zie deel 1 als je niet weet wat het is seriële wachtrij door het instellen van maxConcurrentOperationCount
= 1
maxConcurrentOperationCount →
Het maximum aantal in de wachtrij bewerkingen die u kunt uitvoeren op hetzelfde moment. De standaard waarde is -1, wat betekent dat het systeem de besluiten

met de instelling maxConcurrentOperationCount
= 2 hebben we een gelijktijdige wachtrij en nu taken zijn het uitvoeren van gelijktijdig als weergegeven in Figuur 6

Activiteiten Afhankelijkheden
Zoals getoond in Figuur 7 zijn we weer creëerde een seriële wachtrij door het toevoegen van afhankelijkheden tussen twee taken. We creëerden twee blok operaties, en we zeggen dat niet beginnen met taak 1 en taak 2 is voltooid door te bellen naar blockOperations1.addDependency(blockOperations2)

Verzending Groep Uitvoering met Behulp van Operations Queue
In deel 2 hebben we gebruikt GGD verzending groep functie blokkeren van een draad tot een of meer taken uitgevoerd. Zoals getoond in Figuur 8 hebben we hetzelfde gedrag geà mplementeerd met behulp van Operation Queues door afhankelijkheden te gebruiken. Dit is erg handig als u geen vooruitgang kunt boeken totdat alle opgegeven taken zijn voltooid.
Zoals getoond in Figuur 8 hebben we drie taken, en we willen het gelijktijdig uitvoeren en wanneer de taken afgerond moeten we noemen enkele methode om aan te geven dat alle taken heeft voltooid en wat we deden
- Gemaakt van een operatie wachtrij
- Aangemaakt drie blokkeren activiteiten die het uitvoeren van taken
- Gemaakt van een afronding blok werking (blockOperations4) die zal starten wanneer alle drie de taken klaar
- Gemaakt
blockOperations4
afhankelijk vanblockOperations1
,blockOperations2
enblockOperations3
wat betekent blockOperations4 wordt uitgevoerd wanneer alle drie de taken voltooid -
waitUntilFinished
→ Blokken uitvoering van de huidige thread totdat de bewerking object afwerkingen zijn taak, aangezien we niet willen blokkeren van de huidige thread die is de belangrijkste wijzen we het met false - deze code wordt Uitgevoerd en “Alle Bewerking is Voltooid” wordt afgedrukt wanneer task1, task2 en task3 zal klaar

Zoals weergegeven in Figuur 9 zijn we gewoon blokkeren van de rode draad door het instellen van waitUntilFinished = true.
Dus de vraag is wanneer het is handig en je krijgt het antwoord in het volgende gedeelte

zoals getoond in Figuur 10 hebben we een dispatch groep gedrag geà mplementeerd met behulp van operation queue zonder enige afhankelijkheden te gebruiken wat we deden hebben we de waitUntilFinished
functie op de juiste manier gebruikt . Als u op achtergrond thread bent kunt u deze thread blokkeren om dit gedrag te bereiken. Ik opzettelijk overgestapt naar achtergrond thread met behulp van DispatchQueue.global().async
methode zie deel 1 Om deze code te begrijpen
we vertelde operation queue run taak 1, Taak 2 en taak 3 op operation queue en blok de huidige thread totdat deze gelijktijdige taken hun uitvoering zal voltooien

voordelen van Operation Queues Over GCD
- de Operation API biedt ondersteuning voor afhankelijkheden. Je kunt heel gemakkelijk complexe afhankelijkheden tussen taken creëren, hoewel je dit in GCD kunt bereiken, maar je moet veel werk doen.
- de nsoperation-en NSOperationQueue-klassen hebben een aantal eigenschappen die kunnen worden waargenomen met behulp van KVO (Key Value Observing). Dit is een ander belangrijk voordeel als u de status van een operatie of operatiewachtrij wilt controleren.
- bewerkingen kunnen worden gepauzeerd, hervat en geannuleerd. Zodra je een taak verstuurt met behulp van Grand Central Dispatch, heb je geen controle of inzicht meer in de uitvoering van die taak. De NSOPERATION API is in dat opzicht flexibeler, waardoor de ontwikkelaar controle heeft over de levenscyclus van de operatie
- de NSOperationQueue voegt ook een aantal voordelen toe aan de mix. U kunt bijvoorbeeld het maximum aantal bewerkingen in de wachtrij opgeven dat gelijktijdig kan worden uitgevoerd. Dit maakt het eenvoudig om te bepalen hoeveel bewerkingen tegelijkertijd worden uitgevoerd of om een seriële operatiewachtrij aan te maken.
aankomende
In het volgende deel zullen we kijken naar het werkelijke gebruik van het maken van aangepaste bewerking
· https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW1