Sobes.tech
Junior

Cos'è GCD (Grand Central Dispatch) e come viene utilizzato nello sviluppo iOS?

sobes.tech AI

Risposta dell'AI

GCD (Grand Central Dispatch) è una tecnologia di basso livello di Apple per il parallelismo, basata su C, ma con wrapper comodi in Swift e Objective-C. Fornisce un meccanismo per gestire le code di lavoro (work items) e la loro esecuzione asincrona o sincrona sui core del processore disponibili.

Concetti principali di GCD:

  1. Code di dispatch: Code per eseguire i compiti. Ce ne sono due tipi:

    • Code seriali: I compiti vengono eseguiti sequenzialmente, uno dopo l'altro. Evitano condizioni di race nell'accesso alle risorse condivise.
    • Code concorrenti: I compiti vengono eseguiti in parallelo (ma l'ordine di avvio e fine non è garantito). Usate per compiti indipendenti che possono essere eseguiti simultaneamente.
    • Queue principale: Una coda sequenziale speciale legata al thread principale dell'applicazione. Usata per aggiornare l'UI. Tutti i compiti relativi all'UI devono essere eseguiti in questa coda.
  2. Work Items (Chiusure/Blocchi): Blocchi di codice che rappresentano un compito da eseguire.

  3. Gruppo di dispatch: Permette di raggruppare i compiti e ricevere notifiche quando tutti sono completati.

  4. Semafori di dispatch: Primitive di sincronizzazione per gestire l'accesso a risorse limitate.

Utilizzo nello sviluppo iOS:

  • Eseguire operazioni pesanti in background: Spostare compiti come richieste di rete, elaborazione di immagini, accesso a database dalla main queue a code in background (ad esempio, code concorrenti globali) per evitare di bloccare l'UI.

    // Eseguire un compito asincrono in una coda globale parallela
    DispatchQueue.global(qos: .userInitiated).async {
        // Operazione pesante
        let result = performHeavyOperation()
    
        // Aggiornare l'UI sul thread principale
        DispatchQueue.main.sync {
            updateUI(with: result)
        }
    }
    
  • Aggiornare l'UI: Sempre eseguire le operazioni di modifica dell'interfaccia utente sulla main queue.

    // Aggiornare l'UI sul thread principale
    DispatchQueue.main.async {
        self.label.text = "Aggiornato!"
    }
    
  • Serializzare l'accesso ai dati: Uso di code seriali personalizzate per l'accesso sincronizzato a risorse condivise modificabili.

    // Esempio di coda seriale per accesso sicuro
    let dataAccessQueue = DispatchQueue(label: "com.myapp.dataaccess")
    
    func updateSharedData(newValue: Int) {
        dataAccessQueue.async {
            // Modifica sicura dei dati condivisi
            sharedData = newValue
        }
    }
    
  • Raggruppare i compiti: Attendere che più compiti asincroni siano completati prima di procedere.

    // Gruppo di compiti
    let group = DispatchGroup()
    
    group.enter() // Inizio compito 1
    performAsyncOperation1 {
        print("Compito 1 completato")
        group.leave()
    }
    
    group.enter() // Inizio compito 2
    performAsyncOperation2 {
        print("Compito 2 completato")
        group.leave()
    }
    
    // Notifica al completamento di tutti i compiti
    group.notify(queue: .main) {
        print("Tutti i compiti sono stati completati, aggiornare UI")
        // Aggiornamento UI
    }
    
  • Esecuzione differita: Eseguire codice dopo un intervallo di tempo.

    // Esecuzione differita dopo 2 secondi
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
        print("Avviato dopo 2 secondi")
    }
    

GCD fornisce un approccio di alto livello ed efficiente alla gestione dei thread rispetto ai thread tradizionali (ad esempio, Thread), delegando la gestione del pool di thread al sistema e consentendo un uso efficiente dei processori multi-core.