【发布时间】:2016-09-06 22:30:25
【问题描述】:
我需要将几个在一个NSOperationQueue 中进行网络调用的NSOperations 链接在一起,然后等待全部完成。
我将所有NSOperations 添加到我的NSOperationQueue,然后调用operationQueue.waitUntilAllOperationsAreFinished()。这可行,但它会无限期地等待,因为 NSOperations 中的回调将操作的状态设置为“已完成”,永远不会被调用。
我正在使用以下NSOperation 子类:
class ConcurrentOperation: NSOperation
{
enum State: String
{
case Ready, Executing, Finished
private var keyPath: String
{
return "is" + self.rawValue
}
}
var state: State = State.Ready {
willSet (newValue)
{
self.willChangeValueForKey(newValue.keyPath)
self.willChangeValueForKey(self.state.keyPath)
}
didSet
{
self.didChangeValueForKey(oldValue.keyPath)
self.didChangeValueForKey(self.state.keyPath)
}
}
}
extension ConcurrentOperation
{
override var ready: Bool {
return super.ready && self.state == .Ready
}
override var executing: Bool {
return self.state == .Executing
}
override var finished: Bool {
return self.state == .Finished
}
override var concurrent: Bool {
return true
}
override var asynchronous: Bool {
return true
}
}
extension ConcurrentOperation
{
override func start()
{
if self.cancelled
{
self.state = .Finished
return
}
self.state = .Executing
self.main()
}
override func cancel()
{
self.state = .Finished
}
}
这是基于 Raywenderlich 教程和 https://gist.github.com/calebd/93fa347397cec5f88233 。
这应该做的是告诉 NSOperationQueue 只有当ConcurrentOperation 的子类中的main() 方法将状态设置为.Finished 时它才完成。 这也是通过操作实现的。
然而,如果我在这样的ConcurrentOperation 子类中构造以下main() 方法,NSOperationQueue 永远不会停止,因为 异步部分永远不会被调用:
override func main()
{
dispatch_async(dispatch_get_main_queue(), {
sleep(1)
self.state = .Finished // never called!
})
}
问题与我在应用中使用的 Firebase-Query 回调相同。
我试图覆盖concurrent: Bool 属性并返回true,但这也不能解决问题。
我怎样才能实现异步任务实际上是在我的ConcurrentOperation 子类'main() 方法中执行的?
谢谢!
【问题讨论】:
-
您在主队列中呼叫
waitUntilAllOperationsAreFinished吗?如果是这样,那么您已经阻塞了主队列并且dispatch_async(dispatch_get_main_queue()...代码没有机会执行 -
我是。即使我在
dispatch_async(_,_)块中这样做,它确实阻塞了主队列。你真棒!谢谢!如果您定期回答我的问题,我会将其标记为正确。 @Paulw11
标签: ios swift asynchronous callback queue