Мне нужно связать несколько NSOperation
s, которые выполняют сетевые вызовы в одном NSOperationQueue
, а затем дождитесь завершения всех операций.Асинхронный обратный вызов в NSOperation внутри NSOperationQueue никогда не называется
Я добавляю все NSOperation
s к моему 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 Tutorial и https://gist.github.com/calebd/93fa347397cec5f88233.
Что это должно сделать, это сказать NSOperationQueue, что только тогда, когда метод main()
в подклассе ConcurrentOperation
устанавливает государство .Finished
его достройки. И это также выполняется операцией.
Однако, если я построить следующий main()
метод в такой ConcurrentOperation
подклассе NSOperationQueue
никогда не останавливается, как асинхронная часть никогда не вызывается:
override func main()
{
dispatch_async(dispatch_get_main_queue(), {
sleep(1)
self.state = .Finished // never called!
})
}
Проблема состоит в том же, с Firebase-Query Callback, который я использую в своем приложении.
Я попытался переопределить свойство concurrent: Bool
и вернуть true
, но это не исправляет его.
Как я могу выполнить, что асинхронные задачи выполняются в моем ConcurrentOperation
подклассе main()
?
Спасибо!
Вы вызываете 'waitUntilAllOperationsAreFinished' в главной очереди? Если это так, то вы заблокировали основную очередь, а код 'dispatch_async (dispatch_get_main_queue() ...» не получает возможности выполнить – Paulw11
. Даже если я делаю это в 'dispatch_async (_, _) 'block, он заблокировал основную очередь. Вы потрясающий! Спасибо! Если вы напишете правильный ответ на мой вопрос, я буду отмечать его как правильно. @ Paulw11 – florianpfisterer