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

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

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

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

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

Любые мысли?

Ответ 1

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

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