Sobes.tech
Middle

Дар бораи механизмҳои бекор кардани амалиётҳо нақл кунед.

sobes.tech AI

Ҷавоб аз AI

Механизмът за анулиране на операции в iOS се основава на използването на протокола Cancellable и свързаните типове.

Основни компоненти:

  1. Cancellable протокол: Определя изискването за наличие на метода cancel(), който инициира анулиране.

    // Фрагмент от дефиницията на протокола
    public protocol Cancellable {
        func cancel()
    }
    
  2. AnyCancellable: Тип-обвивка, която съхранява всеки тип, съответстващ на Cancellable, и автоматично извиква cancel() при деинициализация. Полезен е за управление на жизнения цикъл на абонаменти/операции.

    // Пример за използване
    var cancellable = AnyCancellable {
        // Действие при анулиране
        print("Операцията е анулирана")
    }
    
    // В scope, където е дефиниран cancellable, при изход той ще извика cancel()
    
  3. В Combine: Вече повечето Publisher-и предоставят абонамент (Subscription), който реализира протокол Cancellable. При извикване на cancel() на Subscription се прекъсва потокът от данни. Обикновено Subscription се обвива в AnyCancellable и се съхранява.

    // Пример в Combine
    import Combine
    
    let publisher = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var cancellable: AnyCancellable? = publisher.sink { completion in
        print("Завършване: \(completion)")
    } receiveValue: { date in
        print("Стойност: \(date)")
    }
    
    // Затваряне след известно време
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        cancellable?.cancel() // Извикване на `cancel()` на `AnyCancellable`
        cancellable = nil // Премахване на референцията
    }
    
  4. Operation и OperationQueue: В стария API също съществува механизъм за анулиране. Класът Operation има метод cancel() и свойство isCancelled. OperationQueue проверява това свойство и не планира изпълнение на отменени операции.

    import Foundation
    
    class MyOperation: Operation {
        override func main() {
            if isCancelled { // Проверка на състоянието на анулиране
                print("Операцията е отменена преди започване")
                return
            }
    
            // Изпълнение на задачата
            for i in 0..<1000 {
                if isCancelled { // Проверка на състоянието на анулиране вътре в задачата
                    print("Операцията е отменена по време на изпълнение")
                    return
                }
                // Тежка работа или API повикване
                print("Стъпка \(i)")
            }
    
            print("Операцията приключи")
        }
    }
    
    let queue = OperationQueue()
    let operation = MyOperation()
    
    queue.addOperation(operation)
    
    // Откaзване на операцията след известно време
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
       operation.cancel() // Извикване на `cancel()`
    }
    
    // Изчакване за завършване (например, на главния поток не трябва да се прави)
    // queue.waitUntilAllOperationsAreFinished()
    

Механизмът за анулиране в iOS е асинхронен и кооперативен. Извикването на cancel() сигнализира за намерението да се анулира операция/поток от данни, но реалното спиране зависи от това как самата операция обработва този сигнал (например, проверявайки isCancelled или реагирайки на анулиране на абонамента).

Управлението на отменяемите обекти (особено AnyCancellable) често се осъществява чрез тяхното съхраняване в колекции (Set<AnyCancellable>) или свойства на обекти, за да се гарантира извикването на cancel() при деинициализация на контейнера или при явно изтриване от колекция.