2016-09-01 2 views
3

я следующий код:Как дождаться завершения всех NSOperations?

func testFunc(completion: (Bool) -> Void) { 
    let queue = NSOperationQueue() 
    queue.maxConcurrentOperationCount = 1 

    for i in 1...3 { 
     queue.addOperationWithBlock{ 
      Alamofire.request(.GET, "https://httpbin.org/get").responseJSON { response in 
       switch (response.result){ 
       case .Failure: 
        print("error") 
        break; 
       case .Success: 
        print("i = \(i)") 
       } 
      } 
     } 
     //queue.addOperationAfterLast(operation) 
    } 
    queue.waitUntilAllOperationsAreFinished() 
    print("finished") 
} 

и выход:

finished 
i = 3 
i = 1 
i = 2 

, но я ожидаю, что следующее:

i = 3 
i = 1 
i = 2 
finished 

Итак, почему queue.waitUntilAllOperationsAreFinished() не Подождите?

ответ

5

Каждая операция, которую вы добавили в очередь, немедленно выполняется, потому что Alamofire.request просто возвращается, не дожидаясь ответа.

Кроме того, существует возможность тупика. Так как блок responseJSON выполняется по основной очереди по умолчанию, блокирование основного потока путем вызова waitUntilAllOperationsAreFinished будет препятствовать выполнению блока завершения вообще.

Во-первых, чтобы устранить проблему взаимоблокировки, вы можете сказать, что Alamofire выполнил блок завершения в другой очереди, во-вторых, вы можете использовать dispatch_group_t для группировки числа асинхронных HTTP-запросов и сохранения основного потока до тех пор, пока все эти запросы в группе завершают выполнение:

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) 
let group = dispatch_group_create() 
for i in 1...3 { 
    dispatch_group_enter(group) 
    Alamofire.request(.GET, "https://httpbin.org/get").responseJSON(queue: queue, options: .AllowFragments) { response in 
    print(i) 
    dispatch_async(dispatch_get_main_queue()) { 
     // Main thread is still blocked. You can update the UI here but it will take effect after all HTTP requests are finished. 
    } 
    dispatch_group_leave(group) 
    } 
} 
dispatch_group_wait(group, DISPATCH_TIME_FOREVER) 
print("finished") 
2

Я предлагаю вам использовать KVO и наблюдать, когда очередь закончила всю задачу, а не блокирует текущий поток, пока все операции не закончатся. Или вы можете использовать зависимости. Взгляните на this SO question

 Смежные вопросы

  • Нет связанных вопросов^_^