2016-09-16 5 views
4

У меня есть ситуация, когда мне нужно сделать два запроса HTTP GET и обрабатывать их результаты только после того, как они завершены. У меня есть обработчик завершения по каждому отдельному сетевому запросу, но это не помогает, поскольку я не знаю, когда извлекаются данные из обоих запросов.Необходимо выполнить два запроса HTTP-сети одновременно (с обработчиком завершения после завершения обоих)

У меня ограниченный опыт работы с GCD, но теперь, когда Swift 3 отсутствует, я пытаюсь выяснить, как выполнять несколько задач и иметь для них один обработчик завершения. Мои исследования показали, что решение GCD или NSOperationQueue может быть решением, которое я ищу. Может ли кто-нибудь помочь предположить, какой инструмент подходит для работы и как выглядит код в Swift 3?

+0

Может использоваться GCD или NSOperationqueue. GCD: проверьте это [http://stackoverflow.com/questions/37805885/how-to-create-dispatch-queue-in-swift-3][1] – user6837640

ответ

12

Вы должны использовать диспетчерские группы, входящие в группу, прежде чем выдать запрос, и оставив группу в обработчик завершения для запроса. Итак, давайте предположим на секунду, что вы имели какой-то метод, который выполняется асинхронный запрос, но поставляется параметр обработчика завершения, который был замыкание, которое будет вызываться, когда сетевой запрос делается:

func perform(request: URLRequest, completionHandler: @escaping() -> Void) { ... } 

Чтобы начать эти два одновременных запросов, и получать уведомления, когда они сделали, вы могли бы сделать что-то вроде:

let group = DispatchGroup() 

group.enter() 
perform(request: first) { 
    group.leave() 
} 

group.enter() 
perform(request: second) { 
    group.leave() 
} 

group.notify(queue: .main) { 
    print("both done") 
} 

Очевидно, что ваша реализация perform(request:) может значительно варьироваться (например, вы, возможно, закрытие передать данные обратно), но шаблон тот же, независимо от того, записываете ли вы свой собственный сетевой код с URLSession или используя Alamofire. Просто используйте группы GCD, входящие в группу при создании запросов и оставляя группу в обработчике завершения асинхронного запроса.

+0

Закрывает ли закрытие group.notify как обработчик завершения обе задачи, добавленные в группу, закончены? Кроме того, когда мы вводим замыкания в группу, как это известно, чтобы приостановить выполнение, пока мы не закончим добавление всех наших запросов? Я спрашиваю, потому что, если он заканчивает первый запрос, прежде чем я добавлю свою вторую, и вызовы уведомляют, а вторая все еще ожидает. Это вообще не проблема? –

+0

Да, замыкание вызывается, когда все вызовы 'enter' были сбалансированы с помощью соответствующих вызовов' leave'. Таким образом, только после того, как все вызовы 'leave' будут получены, будет вызываться блок группы« уведомление ». – Rob

+0

Приносим извинения за заграждение вопросов, но разве это не означает, что первая функция оставляет группу, а уведомление вызывается до того, как вторая функция будет введена в группу? –

-1

How do I write dispatch_after GCD in Swift 3? Для этого вы можете использовать dispatch_group. Например (ObjC код):

dispatch_group_t group = dispatch_group_create(); 

//startOperation1 
dispatch_group_enter(group); 

//finishOpeartion1 
dispatch_group_leave(group); 


//startOperation2 
dispatch_group_enter(group); 

//finishOpeartion2 
dispatch_group_leave(group); 


//Handle both operations completion 
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
//code here 
});