Sobes.tech
Middle

Papaskink man apie operacijų atšaukimo mechanizmą.

sobes.tech AI

Atsakymas iš AI

iOS operacijų atšaukimo mechanizmas grindžiamas Cancellable protokolu ir susijusiais tipais.

Pagrindiniai komponentai:

  1. Cancellable protokolas: Nustato reikalavimą turėti metodą cancel(), kuris inicijuoja atšaukimą.

    // Protokolo apibrėžimo fragmentas
    public protocol Cancellable {
        func cancel()
    }
    
  2. AnyCancellable: Tipas-apvalkalas, kuris saugo bet kurį Cancellable atitinkantį tipą ir automatiškai iškviečia cancel() deiniatizacijos metu. Naudinga valdyti prenumeratų/operacijų gyvavimo ciklą.

    // Pavyzdys naudojimo
    var cancellable = AnyCancellable {
        // Atšaukimo veiksmas
        print("Operacija atšaukta")
    }
    
    // Scope viduje, kur yra apibrėžtas cancellable, išėjus jis iškvies `cancel()`
    
  3. Atšaukimas Combine framework'e: Dauguma Publisher teikia prenumeratą (Subscription), kuri įgyvendina Cancellable. Iškvietus cancel() Subscription, duomenų srautas sustoja. Paprastai Subscription įpakuojama į AnyCancellable ir saugoma.

    // Pavyzdys Combine'e
    import Combine
    
    let publisher = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var cancellable: AnyCancellable? = publisher.sink { completion in
        print("Užbaigimas: \(completion)")
    } receiveValue: { date in
        print("Reikšmė: \(date)")
    }
    
    // Atšaukimas po tam tikro laiko
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        cancellable?.cancel() // `cancel()` iš `AnyCancellable`
        cancellable = nil // nuorodos ištrynimas
    }
    
  4. Operation ir OperationQueue: Senesniuose API taip pat yra atšaukimo mechanizmas. Operation klasė turi metodą cancel() ir savybę isCancelled. OperationQueue tikrina šią savybę ir neplanuoja vykdyti atšauktų operacijų.

    import Foundation
    
    class MyOperation: Operation {
        override func main() {
            if isCancelled { // atšaukimo būsenos patikrinimas
                print("Operacija atšaukta prieš pradžią")
                return
            }
    
            // Darbo vykdymas
            for i in 0..<1000 {
                if isCancelled { // atšaukimo būsenos patikrinimas viduje
                    print("Operacija atšaukta vykdymo metu")
                    return
                }
                // Sudėtingas darbas arba API iškvietimas
                print("Žingsnis \(i)")
            }
    
            print("Operacija baigta")
        }
    }
    
    let queue = OperationQueue()
    let operation = MyOperation()
    
    queue.addOperation(operation)
    
    // Atšaukimas po tam tikro laiko
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
       operation.cancel() // `cancel()` iškvietimas
    }
    
    // Laukti pabaigos (pavyzdžiui, realioje programoje nereikėtų taip daryti pagrindiniame sraute)
    // queue.waitUntilAllOperationsAreFinished()
    

iOS atšaukimo mechanizmas yra asinchroninis ir kooperatyvus. cancel() iškvietimas signalizuoja apie ketinimą atšaukti operaciją/srautą, tačiau faktinis sustojimas priklauso nuo to, kaip pati operacija apdoroja šį signalą (pvz., tikrindama isCancelled arba reaguodama į atšaukimo prenumeratą).

Gali būti valdomi atšaukiami objektai (ypač AnyCancellable) dažnai saugomi kolekcijose (Set<AnyCancellable>) arba objektų savybėse, kad būtų garantuotas cancel() iškvietimas deiniatizacijos metu arba ištraukimo iš kolekcijos metu.