Sobes.tech
Middle

Co je lepší použít: NSOperationQueue nebo GCD?

sobes.tech AI

Odpověď od AI

Výběr mezi NSOperationQueue a GCD závisí na konkrétních požadavcích úkolu.

GCD (Grand Central Dispatch) - nízkoúrovňové C API pro paralelní programování, založené na konceptu front.

NSOperationQueue - vysokourovňové Objective-C/Swift API, postavené nad GCD. Nabízí další funkce.

Hlavní rozdíly:

Vlastnost GCD NSOperationQueue
Úroveň API Nízkoúrovňová Vyšší úroveň
Typ úkolu Bloky (closures ve Swiftu) Objekt Operation
Závislosti Není vestavěná podpora Podpora závislostí mezi operacemi
Priorita Podporuje Podporuje, s možností změny
Zrušení úkolu Těžko realizovatelné Snadno realizovatelné přes cancel()
Monitoring Není vestavěný Má vlastnosti pro monitoring (isExecuting, isFinished)
Maximální počet paralelních úkolů Přímá kontrola není možná Lze nastavit maxConcurrentOperationCount
Dědičnost Nepoužitelné u bloků Lze dědit pro tvorbu vlastních operací

Kdy používat GCD:

  • Když je potřeba maximální výkon a minimální režie.
  • Pro jednoduché úkoly na pozadí, které nevyžadují složitou logiku nebo závislosti.
  • Při práci s nízkoúrovňovými API.

Například, pro provedení krátkého CPU-bound úkolu na pozadí:

// DispatchQueue.global(qos: .userInitiated) - obecná fronta s určenou prioritou.
// async - asynchronní provedení bloku kódu.
DispatchQueue.global(qos: .userInitiated).async {
    // Provádění náročného úkolu
    let result = self.performExpensiveCalculation()

    // Přepnutí na hlavní frontu pro aktualizaci UI
    DispatchQueue.main.async {
        self.updateUI(with: result)
    }
}

Použití NSOperationQueue:

  • Když mají úkoly závislosti a musí být prováděny v určitém pořadí.
  • Když chcete snadno zrušit úkoly nebo sledovat jejich stav.
  • Když je potřeba kontrolovat maximální počet současně probíhajících úkolů.
  • Pro složitější nebo dlouhotrvající úkoly.
  • Když je potřeba vytvářet znovu použitelné, kapsulované jednotky práce (Operation).

Příklad s závislostí:

import Foundation

// Úkol pro načítání dat
let downloadOperation = BlockOperation {
    print("Načítání dat...")
    Thread.sleep(forTimeInterval: 2) // Simulace zpoždění
    print("Data načtena.")
}

// Úkol pro zpracování dat, závisí na načítání
let processOperation = BlockOperation {
    print("Zpracování dat...")
    Thread.sleep(forTimeInterval: 1) // Simulace zpoždění
    print("Data zpracována.")
}

// Přidání závislosti: processOperation čeká na dokončení downloadOperation
processOperation.addDependency(downloadOperation)

// Vytvoření fronty operací
let operationQueue = OperationQueue()

// Přidání operací do fronty
operationQueue.addOperation(downloadOperation)
operationQueue.addOperation(processOperation)

// Čekání na dokončení všech operací (pro demonstrační účely, v reálné aplikaci obvykle ne)
operationQueue.waitUntilAllOperationsAreFinished()
print("Všechny operace dokončeny.")

Závěr:

  • Pro jednoduché, nezávislé úkoly a maximální výkon se často volí GCD.
  • Pro složitější scénáře s závislostmi, zrušením a sledováním je vhodnější NSOperationQueue.

NSOperationQueue přidává vrstvu abstrakce a funkcionality nad GCD, což jej činí pohodlnějším pro některé úkoly, ale s menšími režijními náklady. Ve většině případů je NSOperationQueue dobrou volbou, pokud jsou jeho dodatečné možnosti potřeba.