简体   繁体   English

完成处理程序和操作队列

[英]Completion handlers and Operation queues

I am trying to do the following approach,我正在尝试采用以下方法,

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)
        }
    }
}

I am checking is there anyway I can get notified when all operations gets completed and then I can call the success handler there.我正在检查是否在那里我可以在所有操作完成时得到通知,然后我可以在那里调用成功处理程序。

I tried checking the apple dev documentation which suggests to use我尝试检查建议使用的苹果开发文档

queue.addBarrierBlock {
   <#code#>
}

but this is available only from iOS 13.0但这仅适用于 iOS 13.0

Pre iOS 13, we'd use dependencies.在 iOS 13 之前,我们会使用依赖项。 Declare a completion operation, and then when you create operations for your network requests, you'd define those operations to be dependencies for your completion operation.声明一个完成操作,然后当您为网络请求创建操作时,您需要将这些操作定义为完成操作的依赖项。

let completionOperation = BlockOperation { ... }

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

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

OperationQueue.main.addOperation(completionOperation)

That having been said, you should be very careful with your operation implementation.话虽如此,您应该非常小心您的操作实施。 Do I correctly infer that downloadTask(with:) returns immediately after the download task has been initiated and doesn't wait for the request to finish?我是否正确推断downloadTask(with:)在下载任务启动后立即返回并且不等待请求完成? In that case, neither dependencies nor barriers will work the way you want.在这种情况下,依赖项和障碍都不会按照您想要的方式工作。

When wrapping network requests in an operation, you'd want to make sure to use an asynchronous Operation subclass (eg https://stackoverflow.com/a/32322851/1271826 ).在操作中包装网络请求时,您需要确保使用异步Operation子类(例如https://stackoverflow.com/a/32322851/1271826 )。

The pre-iOS 13 way is to observe the operationCount property of the operation queue iOS 13 之前的方式是观察操作队列的operationCount属性

var observation : NSKeyValueObservation?

...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM