Обработчики завершения и очереди операций - PullRequest
1 голос
/ 03 февраля 2020

Я пытаюсь сделать следующий подход,

let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 10

func registerUser(completionHandler: @escaping (Result<Data, Error>) -> Void) -> String {
        self.registerClient() { (result) in
        switch result {
            case .success(let data):
                self.downloadUserProfile(data.profiles)
            case .failure(let error):
                return self.handleError(error)
        }
    }
  }

func downloadUserProfile(urls: [String]) {
    for url in urls {
        queue.addOperation {
            self.client.downloadTask(with: url)
        }
    }
}

Я проверяю, есть ли там, в любом случае, я могу получать уведомления, когда все операции завершаются, и затем я могу вызвать обработчик успеха там.

Я попытался проверить документацию для разработчиков Apple, в которой предлагается использовать

queue.addBarrierBlock {
   <#code#>
}

, но это доступно только с iOS 13.0

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Pre iOS 13, мы будем использовать зависимости. Объявите операцию завершения, а затем, когда вы создаете операции для сетевых запросов, вы определяете эти операции как зависимости для вашей операции завершения.

let completionOperation = BlockOperation { ... }

let networkOperation1 = ...
completionOperation.addDependency(networkOperation1)
queue.addOperation(networkOperation1)

let networkOperation2 = ...
completionOperation.addDependency(networkOperation2)
queue.addOperation(networkOperation2)

OperationQueue.main.addOperation(completionOperation)

Сказав это, вы должны быть очень осторожны с реализацией своей операции. Правильно ли я понимаю, что downloadTask(with:) возвращается сразу после запуска задачи загрузки и не ожидает завершения запроса sh? В этом случае ни зависимости, ни барьеры не будут работать так, как вы хотите.

При переносе сетевых запросов в операции вы должны обязательно использовать асинхронный подкласс Operation (например, { ссылка }).

0 голосов
/ 03 февраля 2020

Предварительным способом iOS 13 является соблюдение свойства operationCount очереди операций

var observation : NSKeyValueObservation?

...

observation = operationQueue.observe(\.operationCount, options: [.new]) { observed, change in
        if change.newValue == 0 {
            print("operations finished")
        }
    }
}
...