Sobes.tech
Junior

Kas yra darbas su srautais, kurie skiriasi nuo pagrindinio (main thread)?

sobes.tech AI

Atsakymas iš AI

Darbas su kitais nei pagrindinis (main thread) srautais iOS leidžia vykdyti užduotis asinchroniškai, neblokuojant pagrindinio UI srauto. Tai yra kritiška programėlės reagavimo išlaikymui, ypač atliekant ilgalaikes operacijas, tokias kaip tinklo užklausos, duomenų apdorojimas ar failų tvarkymas.

Pagrindiniai mechanizmai darbui su foniniais srautais yra:

  1. GCD (Grand Central Dispatch):

    • Žemo lygio C orientuota biblioteka.
    • Naudoja užduočių eilutes (DispatchQueue).
    • Gali kurti lygiagrečias ir eilės eilutes.
    • Leidžia dirbti su globaliomis eilėmis (concurrent) ir pagrindinio srauto eile (main).
    • Paprasta naudoti vykdant kodų blokus foniniame režime.
    // Kodo vykdymas globalioje eilėje
    DispatchQueue.global(qos: .userInitiated).async {
        // Ilgalaikė užduotis
        print("Užduotis įvykdyta foniniame sraute")
    
        // Grįžimas į pagrindinį srautą UI atnaujinimui
        DispatchQueue.main.async {
            // UI atnaujinimas
            print("UI atnaujintas pagrindiniame sraute")
        }
    }
    
  2. Operation Queue (Operation ir OperationQueue):

    • Aukštesnio lygio abstrakcija, sukurta remiantis GCD.
    • Atvaizduoja užduotis kaip Operation objektus.
    • Leidžia valdyti priklausomybes tarp operacijų, jas sustabdyti, atšaukti ir atnaujinti.
    • Patogiau valdyti sudėtingas tarpusavyje susijusias užduotis.
    import Foundation
    
    class MyOperation: Operation {
        override func main() {
            if self.isCancelled { return }
            // Ilgalaikė užduotis
            print("Operation įvykdyta foniniame sraute")
    
            if self.isCancelled { return }
            // Grįžimas į pagrindinį srautą UI atnaujinimui
            OperationQueue.main.addOperation {
                 print("UI atnaujintas iš Operation")
            }
        }
    }
    
    // Sukurti operacijų eilę
    let queue = OperationQueue()
    queue.qualityOfService = .userInitiated
    
    // Pridėti operacijas į eilę
    queue.addOperation(MyOperation())
    
  3. Async/Await (Concurrency):

    • Šiuolaikinis Swift mechanizmas asinchroniniam programavimui.
    • Naudoja raktinius žodžius async asinchroninėms funkcijoms ir await jų užbaigimui.
    • Supaprastina asinchroninio kodo rašymą ir skaitymą, išvengiant "callback hell".
    • Automatiškai valdo srautų perjungimą.
    func fetchData() async -> Data? {
        // Tinklo užklausos imitacija
        try? await Task.sleep(nanoseconds: 1_000_000_000)
        print("Duomenys gauti asinchroninėje funkcijoje")
        return Data()
    }
    
    // Asinchroninės funkcijos iškvietimas iš Task
    Task {
        if let data = await fetchData() {
            print("Gauti duomenys: \(data.count)")
            // Automatiškai vykdoma tinkamu kontekstu (gali būti main UI atnaujinimui)
        }
    }
    

Svarbūs aspektai:

  • Srauto saugumas (Thread Safety): Būtina būti atsargiems prieinant prie bendrų išteklių (kintamųjų, objektų) iš skirtingų srautų, kad išvengtumėte duomenų lenktynių (data races). Tam naudojamos užraktai (locks), eilės (siekiant serializuoti prieigą) arba atomarinės operacijos.
  • UI atnaujinimas: Visada atnaujinkite naudotojo sąsajos elementus tik pagrindiniame sraute (DispatchQueue.main arba OperationQueue.main). Bandymas atnaujinti UI iš foninio srauto sukels klaidas ar nenuspėjimą elgesį.
  • Optimizacija: Pasirinkite tinkamą mechanizmą pagal užduoties pobūdį. GCD yra paprastesnis paprastoms asinchroninėms užduotims, Operation Queue — sudėtingų užklausų valdymui, Async/Await — šiuolaikiniam struktūrizuotam asinchroniniam kodui.
  • Prioritetai (QoS): Nurodykite paslaugos kokybę (Quality of Service) užduotims, kad sistema galėtų tinkamai valdyti jų prioritetus ir paskirstyti išteklius.
Mechanizmas Abstrakcijos lygis Priklausomybių valdymas Atšaukimas / Sustabdymas Paprastumas naudoti
GCD Žemas Nėra (tik bazinis) Sudėtingas Vidutinis
Operation Queues Aukštas Taip Lengva Vidutinis / Aukštas
Async/Await Aukštas Iš dalies įmontuotas Lengva (Task) Aukštas

Tinkamas foninių srautų naudojimas yra kritiškai svarbus kuriant našias ir reaguojančias iOS programas.