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.