2016-09-21 2 views
0

Я использую swift 3.0 под управлением iOS 10.0, и я хочу создать код, который срабатывает, когда выполняется пакетное условие.Решение для отслеживания партии HTTP-запросов в swift 3.0

for i in 0 ..< rex { 
    async code, disappears and does it stuff 
} 

Представьте код асинхронной представляет собой набор запросов URL, что в основном фоне, как только я петлю через них. Теперь, как я могу запустить больше кода, когда будут завершены запросы «rex»?

Я думал о настройке таймера, чтобы смотреть и проверять каждую секунду, но это, безусловно, не очень хорошее решение.

Я подумал о том, чтобы начать другой поток, чтобы просто наблюдать за собираемыми данными и стрелять, когда его квота заполнена, но это хуже, чем таймер.

Я собираюсь включить тест в конце каждого запроса URL-адреса, чтобы проверить, завершено ли оно последним, и чем использует NotificationCenter, но является ли это оптимальным решением?

ответ

3

Хотя OperationQueue (aka NSOperationQueue) является хорошим выбором во многих случаях, он не подходит для вашего случая использования. Проблема в том, что запросы URL-адресов вызываются асинхронно. Ваш NSOperation закончит, прежде чем вы получите ответ от webservice.

Использование DispatchGroup вместо

let group = DispatchGroup() 

// We need to dispatch to a background queue because we have 
// to wait for the response from the webservice 
DispatchQueue.global(qos: .utility).async { 
    for i in 0 ..< rex { 
     group.enter()   // signal that you are starting a new task 
     URLSession.shared.dataTask(with: urls[i]) { data, response, error in 
      // handle your response 
      // .... 
      group.leave()  // signal that you are done with the task 
     }.resume() 
    } 

    group.wait()    // don't ever call wait() on the main queue 

    // Now all requests are complete 
} 
+0

Я использую alamofire, на самом деле не URLSession, и не мог видеть, как возобновлено изображение на картинке, но неважно. В любом случае это отлично работает !! Это самый полезный маленький код, который я узнал в этом месяце, в этом году! Я бы проголосовал за это дважды, если бы мог ... – user3069232

1

Так что я уверен, что вы хотите, может быть found here. В основном вы хотите использовать GCD и завершить закрытие. Это одна строка кода, которая всегда заставляет меня хихикать. Более длинный пост на тему is here.

+0

Благодаря Мори, ваше сообщение полезно тоже. Постараюсь и лучше понять этот маленький камень. – user3069232

0

Что вы ищете, это NSOperationQueue (или OperationQueue в Swift 3). Вот Swift tutorial (может быть немного устаревшим). Вот Apple documentation on it - в Swift 3 они отбрасывают все префиксы NS, поэтому это OperationQueue/Operation.

В принципе, вы должны добавить каждый из ваших задач URL как Operation к OperationQueue, и есть «сделано» Operation с каждым из ваших задач URL как зависимость, и добавить его в очередь. Затем, как только все ваши задачи URL будут выполнены, он будет вызывать вашу операцию, которую вы можете настроить, чтобы делать все, что хотите.

Возможно, вам понадобится подкласс Operation, чтобы вы могли корректно обновить свойства и isFinished. This question may be of some help here.

+0

Спасибо за прокладку, хотя я думаю, что следующий комментарий прав, URL-адрес будет сообщать о задаче, выполняемой до возвращения HTTP-запроса. – user3069232

+0

Вот почему вы подклассифицируете 'Operation' и обновляете свойства' isExecuting'/'isFinished' на основе того, когда ваш HTTP-запрос запускается/заканчивается. Очень типичный вариант использования. – shim

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