Sobes.tech
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.