Почему я должен выбрать GCD над NSOperation и блоками для приложений высокого уровня?

в справочнике Apple Grand Central Dispatch говорится:

"...если ваше приложение должно работать на уровне Unix система-например, если ей нужно манипулировать файловыми дескрипторами, Mach порты, сигналы или таймеры. GCD не ограничивается системным уровнем приложения, но прежде чем использовать его для приложений более высокого уровня, вы следует рассмотреть, предоставляются ли аналогичные функции в Cocoa (через Объекты NSOperation и block) было бы проще использовать или больше подходит для ваших нужд.".

http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

Я не могу на самом деле думать о ситуациях, для приложений высокого уровня, в которых использование GCD является обязательным и NSOperation может/не должен использоваться.

какие мысли?

5 ответов


речь идет о том же самом, что и Крис Хансон в своей статье"когда использовать NSOperation против GCD":

прямой ответ является общим руководством для всех приложений разработка:

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

в данном конкретном случае, это означает, что, когда написание какао приложения, вы обычно должны использовать NSOperation, а не использование GCD напрямую. Не из-за разницы в эффективности, но поскольку NSOperation обеспечивает абстракцию более высокого уровня поверх механизмы ГКД.

В общем, я согласен с этим. NSOperation и NSOperationQueue обеспечивают поддержку зависимостей и одной или двух других вещей, которых нет у блоков и очередей GCD, и они абстрагируют детали нижнего уровня о том, как выполняются параллельные операции. Если вам нужна эта функциональность, NSOperation-очень хороший способ пойти.

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

первая причина происходит от профилирования в моем приложения, где я обнаружил, что процесс выделения и освобождения объекта NSOperation занимает значительное количество ресурсов процессора при работе с небольшими и частыми действиями, такими как рендеринг фрейма OpenGL ES на экран. Блоки GCD полностью устранили эти накладные расходы, что привело к значительным улучшениям производительности.

вторая причина более субъективна, но я считаю, что мой код чище при использовании блоков, чем NSOperations. Быстрый захват области, разрешенной a блок и встроенный характер их делают для меньшего кода, потому что вам не нужно создавать пользовательские подклассы NSOperation или связывать параметры, которые будут переданы в операцию, и более описательный код, на мой взгляд, потому что вы можете поместить код для запуска в очередь в точке, где он запускается.

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


  • предпочитают GCD, где задача не очень сложная и оптимальная производительность процессора - это.
  • предпочитайте NSOperationQueue, где задача сложна и требует отмена или приостановка управления блоком и зависимостями.

GCD-это легкий способ представления единиц работы, которые будут выполняться одновременно. Вы не планируете эти единицы работы; система заботится о планировании для вас. Добавление зависимости среди блоков может быть головная боль. Отмена или приостановка блока создает дополнительную работу для вас как разработчика!

NSOperation и NSOperationQueue добавляют немного дополнительных накладных расходов по сравнению с GCD, но вы можете добавить зависимость между различными операциями. Вы можете повторно использовать, отменить или приостановить операции. NSOperation совместим с наблюдением ключевых значений (KVO); например, вы можете запустить NSOperation, прослушав NSNotificationCenter.

подробные объяснение, обратитесь к этому вопросу:NSOperation vs Grand Central Dispatch


Ну, NSOperation не имеет эквивалентов dispatch_source_t, dispatch_io, dispatch_data_t, dispatch_semaphore_t и т. д... Это также несколько выше накладных расходов.

с другой стороны, libdispatch не имеет эквивалентов зависимостей операций, приоритетов операций (приоритеты очередей несколько отличаются) или KVO для операций.


есть две вещи, которые NSOperationQueue может сделать, что GCD не делает: второстепенная-это зависимости (добавьте операцию в очередь, но скажите ей, чтобы она выполнялась только после завершения некоторых других операций), и большая-это то, что NSOperation дает вам объект, который может получать сообщения во время выполнения задачи, в отличие от GCD, который имеет блоки, которые не могут получать сообщения, кроме как очень ограниченным способом. Вам либо нужны эти две функции, либо нет. Если вы этого не сделаете, использование GCD-это просто намного проще в использовании.

вот почему полезные примеры NSOperation всегда довольно сложны. Если бы они были простыми, вы бы использовали GCD вместо этого. Обычно вы создаете подкласс NSOperation, который будет представлять собой значительный объем работы, или используете тот, который создал кто-то другой.


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

Я не могу придумать случай, когда вам пришлось бы использовать GCD над NSOperation, но это не значит, что такого случая не существует. Я, однако, согласен с общим настроением с точки зрения наилучшей практики кодирования:

Если у вас есть пара инструментов, которые подходят для работы (и в этом случае у вас есть NSOperation против блока GCD), используйте класс с самым высоким уровнем абстракция (т. е. API самого высокого уровня). Мало того, что обычно проще использовать / меньше кода, Вы также получите от потенциальных будущих улучшений, введенных в API более высокого уровня.