11

Когда вам нужно что-то выполнить в основном потоке в блоке завершения сетевой задачи или операции, какой из этих способов получить ее будет наиболее подходящим и почему ?:OperationQueue.main vs DispatchQueue.main

  • OperationQueue.main.addOperation
  • DispatchQueue.main.async
+0

Проверить это ссылки - http://stackoverflow.com/questions/7651551/why-should-i-choose-gcd-over-nsoperation-and-blocks-for -high-level-applications/7654476 # 7654476 и http://stackoverflow.com/questions/10373331/nsoperation-vs-grand-central-dispatch – Rajat

ответ

4

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

Ссылка: Apple Doc

Класс NSOperationQueue регулирует выполнение набора объектов операции. После добавления в очередь в этой очереди остается операция до тех пор, пока она не будет явно отменена или не завершит выполнение своей задачи. Операции в очереди (но еще не выполняющиеся) сами организованы в соответствии с уровнями приоритета и зависимостями между операционными объектами и выполняются соответствующим образом. Приложение может создавать несколько очередей операций и отправлять операции любому из них.

Ссылка: Apple Doc

Таким образом, вы должны предпочесть DispatchQueue.main.async, когда вы хотите выполнить что-то на главном потоке от завершения блока любого сетевого вызова. Особенно, если это связано с UI Updates! И если ваша задача сложная, я имею в виду, если вам требуется дополнительная операция при выполнении задачи, тогда вы можете пойти с OperationQueue.main.addOperation, иначе DispatchQueue.main.async даст более оптимальную производительность сравнительно!

+0

Это не отвечает на вопрос, какую очередь они должны выбрать. – MrMage

+0

@MrMage Да, отредактированный ответ немного! – Lion

8

Подробнее о различиях между двумя типами очередей см. В комментарии Лев.

Оба подхода будут работать. Тем не менее, NSOperation в основном необходим, когда требуется более продвинутое планирование (включая зависимости, отмена и т. Д.). Таким образом, в этом случае просто

DispatchQueue.main.async { /* do work */ } 

будет в порядке. Это было бы эквивалентно

dispatch_async(dispatch_get_main_queue(), ^{ /* do work */ }); 

в Objective-C, который также, как я хотел бы сделать это на этом языке.

+1

@ Lion: Я не согласен с вашим выбором форматирования всех подчеркнутых слов с обратными выводами как «code». Пожалуйста, подумайте о том, чтобы использовать символы подчеркивания, чтобы сделать их _italic_. – MrMage

6

Когда использовать NSOperation

NSOperation API отлично подходит для инкапсулирования хорошо определенные блоки функциональности. Например, вы можете использовать подкласс NSOperation для инкапсуляции последовательности входа в приложение.

Управление зависимостями является глазурью на торте. Операция может иметь зависимости от других операций, и это очень мощная функция, которой не хватает в Grand Central Dispatch. Если вам нужно выполнить несколько задач в определенном порядке, то операции являются хорошим решением.

Вы можете перейти за борт с операциями, если вы создаете десятки операций за короткий промежуток времени. Это может привести к проблемам с производительностью из-за накладных расходов, присущих NSOperation API.

Когда использовать Grand Central Dispatch

Grand Central Dispatch идеально подходит, если вам просто нужно направить блок кода в последовательную или параллельную очередь.

Если вы не хотите испытывать затруднения при создании NSOperation subclass для тривиальной задачи, то Grand Central Dispatch - отличная альтернатива. Другим преимуществом Grand Central Dispatch является то, что вы можете сохранить связанный код вместе. Взгляните на следующий пример.

let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in 
// Process Response 
... 

dispatch_async(dispatch_get_main_queue(), {() -> Void in 
    // Update User Interface 
    ... 
}) 
}) 

В обработчик завершения задания данных, мы обрабатываем ответ и обновить пользовательский интерфейс, направив замыкание (или блока) к основной очереди. Это необходимо, потому что мы не знаем, в какой поток выполняется обработчик завершения, и это скорее всего фоновый поток.

Цитируется дословно this source