Sobes.tech
Middle

Povedz mi o mechanizme zrušenia v operáciách.

sobes.tech AI

Odpoveď od AI

Mechanizmus zrušenia operácií v iOS je založený na použití protokolu Cancellable a súvisiacich typov.

Hlavné komponenty:

  1. Cancellable protokol: Určuje požiadavku na metódu cancel(), ktorá spúšťa zrušenie.

    // Fragment definície protokolu
    public protocol Cancellable {
        func cancel()
    }
    
  2. AnyCancellable: Typový obal, ktorý uchováva akýkoľvek typ odpovedajúci Cancellable, a automaticky volá cancel() pri deinitializácii. Je vhodný na správu životného cyklu odberov/operácií.

    // Príklad použitia
    var cancellable = AnyCancellable {
        // Akcia zrušenia
        print("Operácia zrušená")
    }
    
    // V rámci scope, kde je definovaný cancellable, pri ukončení sa zavolá `cancel()`
    
  3. V Combine: Väčšina publisherov poskytuje odber (Subscription), ktorý implementuje protokol Cancellable. Pri volaní cancel() na Subscription sa tok dát ukončí. Zvyčajne je Subscription obalená v AnyCancellable a uchováva sa.

    // Príklad v Combine
    import Combine
    
    let publisher = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var cancellable: AnyCancellable? = publisher.sink { completion in
        print("Dokončenie: \(completion)")
    } receiveValue: { date in
        print("Hodnota: \(date)")
    }
    
    // Zrušiť po určitom čase
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        cancellable?.cancel() // Volanie `cancel()` na `AnyCancellable`
        cancellable = nil // Odstránenie odkazu
    }
    
  4. Operation a OperationQueue: V starom API tiež existuje mechanizmus na zrušenie. Trieda Operation má metódu cancel() a vlastnosť isCancelled. OperationQueue kontroluje túto vlastnosť a nezahajuje vykonávanie zrušených operácií.

    import Foundation
    
    class MyOperation: Operation {
        override func main() {
            if isCancelled { // Kontrola stavu zrušenia
                print("Operácia bola zrušená pred začatím")
                return
            }
    
            // Vykonanie úlohy
            for i in 0..<1000 {
                if isCancelled { // Kontrola stavu zrušenia vnútri úlohy
                    print("Operácia bola zrušená počas vykonávania")
                    return
                }
                // Ťažká práca alebo API volanie
                print("Krok \(i)")
            }
    
            print("Operácia dokončená")
        }
    }
    
    let queue = OperationQueue()
    let operation = MyOperation()
    
    queue.addOperation(operation)
    
    // Zrušiť operáciu po určitom čase
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
       operation.cancel() // Volanie `cancel()`
    }
    
    // Čakanie na dokončenie (napríklad, na hlavnom vlákne to nerobte)
    // queue.waitUntilAllOperationsAreFinished()
    

Mechanizmus zrušenia v iOS je asynchrónny a kooperatívny. Volanie cancel() signalizuje zámer zrušiť operáciu/tok dát, ale skutočné zastavenie závisí od toho, ako sama operácia spracováva tento signál (napríklad kontrolou isCancelled alebo reakciou na zrušenie odberu).

Správa objektov, ktoré je možné zrušiť (najmä AnyCancellable), sa často vykonáva ich uložením do kolekcií (Set<AnyCancellable>) alebo vlastností objektov, aby sa zabezpečilo volanie cancel() pri deinitializácii kontajnera alebo pri priamej odstránení z kolekcie.