Grand Central Dispatch (GCD) è arrivato su iOS e macOS nel 2009 come sistema low-level per organizzare codice concorrente e asincrono (multithreading), basato su code — DispatchQueue. GCD si è rivelato molto più conciso rispetto alla gestione manuale dei thread, fornendo un'esecuzione sicura delle attività, sincronizzazione e un API conveniente.
L'asincronicità e la multithreading sono tradizionalmente una fonte di molti problemi: race condition, deadlock, blocchi live dell'interfaccia e crash complessi. L'uso improprio delle code o il tentativo di accedere all'interfaccia utente da un thread non-main porta a bug.
Swift consente di creare facilmente lavoro in background e tornare in modo sicuro al thread principale per aggiornare l'interfaccia utilizzando code globali e personalizzate. Utilizza DispatchQueue per lavori asincroni e DispatchGroup se deve attendere il completamento di un insieme di attività asincrone.
Esempio di codice:
let backgroundQueue = DispatchQueue(label: "background", qos: .background) backgroundQueue.async { // eseguito nel thread di lavoro let image = downloadImage() DispatchQueue.main.async { // aggiornamento sicuro dell'UI imageView.image = image } }
Caratteristiche principali:
Cosa succede se chiamo sync sulla coda principale dal thread principale?
Si verifica un deadlock: il thread principale attende l'esecuzione dell'attività su se stesso e l'app si " blocca".
DispatchQueue.main.sync { // DEADLOCK }
Può DispatchQueue.serial eseguire attività in parallelo?
No, la coda seriale esegue sempre le attività una alla volta, tuttavia, se si creano più code seriali, queste vengono eseguite in parallelo tra loro.
È consentito aggiornare l'interfaccia non dal thread principale?
No, qualsiasi manipolazione con UIKit (o rendering di SwiftUI View) può essere effettuata solo da DispatchQueue.main. La violazione porterà a comportamenti instabili e crash.
Nel thread di lavoro vengono scaricati dati, poi si aggiorna immediatamente l'UI — l'app a volte si blocca o l'interfaccia si congela. Inoltre, si utilizza uno stato mutabile condiviso tra i thread senza sincronizzazione.
Vantaggi:
Svantaggi:
Organizzazione di tutti gli aggiornamenti UI solo su DispatchQueue.main, code dedicate per lavorare con grandi quantità di dati, utilizzo di DispatchGroup per controllare il completamento delle attività asincrone.
Vantaggi:
Svantaggi: