NSOperationQueue内部的NSOperation中的asynchronouscallback从来没有被调用过

我需要链接几个NSOperation s在一个NSOperationQueue做networking调用,然后等待所有完成。

我将所有的NSOperation添加到我的NSOperationQueue ,然后调用operationQueue.waitUntilAllOperationsAreFinished() 。 这是有效的,但是它会无限期地等待,因为NSOperations的callback将操作的状态设置为“已完成”,因此永远不会被调用。

我正在使用以下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永远不会停止,因为从不调用asynchronous部分

 override func main() { dispatch_async(dispatch_get_main_queue(), { sleep(1) self.state = .Finished // never called! }) } 

问题与我在应用程序中使用的Firebase-Querycallback相同。

我试图重写concurrent: Bool属性并返回true ,但是这并不解决它。

我怎么能完成asynchronous任务实际上是在我的ConcurrentOperation子类的main()方法中执行?

谢谢!

如果您在主队列上调用waitUntilAllOperationsAreFinished ,则会阻塞主队列。 一旦主队列被阻塞, dispatch_async(dispatch_get_main_queue(),将无法执行,因为您已经创build了一个死锁;需要执行以解锁主队列的任务已经在阻塞的主队列上进行了调度,因此它将从不运行,永远不能运行。

您需要在自己的队列上分派waitUntilAllOperationsAreFinished