Middle
Kas geriau naudoti: NSOperationQueue ar GCD?
sobes.tech AI
Atsakymas iš AI
Pasirinkimas tarp NSOperationQueue ir GCD priklauso nuo konkrečių užduoties reikalavimų:
GCD (Grand Central Dispatch) - žemo lygio C API paraleliniam programavimui, pagrįstas eilių koncepcija:
NSOperationQueue - aukšto lygio Objective-C/Swift API, sukurtas virš GCD. Jis siūlo papildomas galimybes:
Pagrindiniai skirtumai:
| Savybė | GCD | NSOperationQueue |
|---|---|---|
| API lygis | Žemo lygio | Aukšto lygio |
| Užduoties tipas | Kodo blokai (closures Swift'e) | Operation objektai |
| Priklausomybės | Neturi vidinės paramos | Parama priklausomybėms tarp operacijų |
| Prioritetas | Palaiko | Palaiko, galima keisti |
| Užduoties atšaukimas | Sunku įgyvendinti | Lengva įgyvendinti cancel() būdu |
| Stebėsena | Neturi vidinės paramos | Yra savybės stebėjimui (isExecuting, isFinished) |
| Maksimalus paralelinių užduočių skaičius | Tiesioginės kontrolės nėra | Galima nustatyti maxConcurrentOperationCount |
| Paveldėjimas | Netaikoma blokams | Galima paveldėti kurti naudotojo operacijas |
Kada naudoti:
- Kai reikalingas maksimalus našumas ir minimalios išlaidos:
- Paprastoms foninėms užduotims, kurios nereikalauja sudėtingos logikos ar priklausomybių:
- Dirbant su žemo lygio API:
Pavyzdys — trumpalaikės CPU ribotos užduoties vykdymas fone:
// DispatchQueue.global(qos: .userInitiated) - bendras eilė su tam tikru prioritetu.
// async - asinchroninis blokų vykdymas:
DispatchQueue.global(qos: .userInitiated).async {
// Resursų intensyvi užduotis
let result = self.performExpensiveCalculation()
// Perjungimas į pagrindinę eilę UI atnaujinimui
DispatchQueue.main.async {
self.updateUI(with: result)
}
}
Kada naudoti NSOperationQueue:
- Kai užduotys turi priklausomybių ir turi būti vykdomos tam tikra tvarka:
- Kai reikia lengvai atšaukti užduotis arba stebėti jų būseną:
- Kai reikia kontroliuoti maksimalų vienu metu vykdomų užduočių skaičių:
- Dėl sudėtingesnių ar ilgalaikių užduočių:
- Kai reikia kurti pakartotinai naudojamas, inkapsuliuotas darbo vienetus (
Operation):
Pavyzdys su priklausomybe:
import Foundation
// Duomenų įkėlimo operacija
let downloadOperation = BlockOperation {
print("Duomenų įkėlimas...")
Thread.sleep(forTimeInterval: 2) // Užklausos imitacija
print("Duomenys įkelti.")
}
// Duomenų apdorojimo operacija, priklausoma nuo įkėlimo
let processOperation = BlockOperation {
print("Duomenų apdorojimas...")
Thread.sleep(forTimeInterval: 1) // Užklausos imitacija
print("Duomenys apdoroti.")
}
// Priklausomybės pridėjimas: processOperation laukia downloadOperation pabaigos
processOperation.addDependency(downloadOperation)
// Operacijų eilės sukūrimas
let operationQueue = OperationQueue()
// Operacijų pridėjimas į eilę
operationQueue.addOperation(downloadOperation)
operationQueue.addOperation(processOperation)
// Laukti, kol visi užbaigs (demonstracijai, realioje programoje dažniausiai ne)
operationQueue.waitUntilAllOperationsAreFinished()
print("Visos operacijos baigtos.")
Išvada:
- Paprastoms, nepriklausomoms užduotims ir maksimaliai našumui dažnai pasirenkamas GCD.
- Sudėtingesniems scenarijams su priklausomybėmis, atšaukimu ir stebėsena, geriau naudoti NSOperationQueue.
NSOperationQueue prideda sluoksnį abstrakcijos ir funkcionalumo virš GCD, padarydama jį patogesnį tam tikroms užduotims, bet su nedideliu papildomu kaštu. Daugeliu atvejų, jei reikalingos jo papildomos galimybės, jis yra geras pasirinkimas.