Skip to main content

La Classe DispatchGroup di Grand Central Dispatch con Swift

R2-D2 ha appena ricevuto un messaggio di importanza vitale dalla Principessa Leia.

Adesso insieme a C-3PO stanno scappando dalla nave dei ribelli prima che le truppe imperiali li catturino.

Si trovano proprio davanti alla capsula di salvataggio, su un cartello appare il seguente messaggio

“Peso massimo 110 Kg. La capsula esploderà in caso di peso maggiore.”

Alle loro spalle gli spari degli Stormtrooper in avvicinamento, hanno esattamente 1 minuto per decidere cosa fare.

Non conoscono il loro peso però possono effettuare 2 chiamate REST per ricevere quell’informazione.

In passato avevano già testato il codice.

Il tempo di risposta di una chiamata è di 40 secondi, siccome le 2 chiamate vengono eseguite in parallelo, il tempo di esecuzione delle 2 chiamate è ancora di 40 secondi.

Il problema è che effettuando queste 2 chiamate asincrone non riescono poi a mettere insieme i risultati, ovvero il contenuto delle variabili c3poMassr2d2Mass.

Infatti le 2 closure (quella nelle righe #4-#5 e quella nelle righe #10-#11) vengono eseguite su 2 thread distinti.

Effettuare le chiamate in modo sequenziale

A quel punto C-3PO considera che effettuando le chiamate in modo sequenziale risolverebbe il problema, in quel caso riuscirebbe ad avere i 2 risultati all’interno dello stesso thread e quindi potrebbero facilmente effettuare la somma dei loro pesi.

Vediamo come aggiorna il codice

Adesso è possibile effettivamente stampare il risultato!

Tuttavia dobbiamo considerare che la seconda chiamata viene avviata solo dopo che la prima è stata completata. Quindi in questo caso il tempo di esecuzione totale è di 40 + 40 secondi. Quindi sebbene stiamo ottenendo il risultato desiderato il tempo di attesa è troppo alto, gli Stormtropers li raggiungeranno in 1 minuto!

DispatchGroup

Grand Central Dispatch, la tecnologia per la gestione dei thread introdotta con Snow Leopard, permette di risolvere il problema in modo elegante.

Alla riga #8 stiamo creando un valore di tipo DispatchGroup.

Successivamente invochiamo un group.enter() prima di avviare una chiamata asincrona (righe #10 e #16).

Ogni volta che invochiamo il metodo .enter(), all’interno del DispatchGroup viene incrementato un contatore che tiene traccia degli eventi che stiamo aspettando vengano completati.

Una volta che ognuna delle 2 chiamate asincrone è terminata, chiamiamo group.leave(). Con questa istruzione segnaliamo al group che un’evento è terminato e che quindi può decrementare il suo contatore interno.

Lo facciamo alle righe #13 e #19.

Infine scriviamo alla riga #22 stiamo chiedendo al group di eseguire nella main queue il codice che scriviamo nella closure segue.

Questo significa che il codice che vedete tra le righe #23 e #28 verrà eseguito solo dopo che le 2 chiamate asincrone sono terminate.

Inoltre essendo le chiamate, appunto, asincrone e non sequenziali, il tempo totale dell’operazione sarà di 40 secondi.

Qui di seguito il codice completo.

Per provarlo create un progetto vuoto con Xcode e poi inseritelo nel file ViewController.swift e premete Play.

Conclusione

Questo contenuto ti è stato offerto gratuitamente, se l’hai trovato utile puoi ricambiare il favore condividendolo con i pulsanti qui sotto!

Trainer • Developer • Writer

Luca Angeletti

Trainer • Developer • Writer

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *