Когда вам нужно что-то выполнить в основном потоке в блоке завершения сетевой задачи или операции, какой из этих способов ее получить будет наиболее подходящим и почему?:
-
OperationQueue.main.addOperation
-
DispatchQueue.main.async
Когда вам нужно что-то выполнить в основном потоке в блоке завершения сетевой задачи или операции, какой из этих способов ее получить будет наиболее подходящим и почему?:
OperationQueue.main.addOperation
DispatchQueue.main.async
Подробнее о различиях между двумя типами очереди см. в комментарии Lion.
Оба подхода будут работать. Однако NSOperation
в основном требуется, когда требуется более продвинутое планирование (включая зависимости, отмена и т.д.). Итак, в этом случае простая
DispatchQueue.main.async { /* do work */ }
будет просто отлично. Это будет эквивалентно
dispatch_async(dispatch_get_main_queue(), ^{ /* do work */ });
в Objective-C, что также я хотел бы сделать это на этом языке.
Когда использовать NSOperation
API NSOperation
отлично подходит для инкапсуляции четко определенных блоков функциональности. Например, вы можете использовать подкласс 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
...
})
})
В обработчике завершения задачи данных мы обрабатываем ответ и обновляем пользовательский интерфейс, отправляя замыкание (или блок) в основную очередь. Это необходимо, потому что мы не знаем, в какой поток выполняется обработчик завершения, и это скорее всего фоновый поток.
Цитата из этот источник
DispatchQueue управляет выполнением рабочих элементов. Каждый рабочий элемент, отправленный в очередь, обрабатывается в пуле потоков, управляемых системой.
Ссылка: Apple Doc
Класс NSOperationQueue регулирует выполнение набора объектов Operation. После добавления в очередь в этой очереди остается операция до тех пор, пока она не будет явно отменена или не завершит выполнение своей задачи. Операции в очереди (но еще не выполняющиеся) сами организованы в соответствии с уровнями приоритета и зависимостями между операционными объектами и выполняются соответствующим образом. Приложение может создавать несколько очередей операций и отправлять операции любому из них.
Ссылка: Apple Doc
Итак, вы должны предпочесть DispatchQueue.main.async
, когда хотите выполнить что-то в основном потоке из блока завершения любого сетевого вызова. Особенно, когда это связано с UI Updates
! И если ваша задача сложная, я имею в виду, если вам требуется дополнительная операция при запуске задачи, вы можете пойти с OperationQueue.main.addOperation
иначе DispatchQueue.main.async
даст более оптимальную производительность сравнительно!