NSOperation vs Grand Central Dispatch


Я изучаю параллельное программирование для iOS. До сих пор я читал о NSOperation/NSOperationQueue и GCD. каковы причины использования NSOperationQueue over GCD и наоборот?

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

8 424

8 ответов:

GCD-это низкоуровневый API на основе C, который позволяет очень просто использовать модель параллелизма на основе задач. NSOperation и NSOperationQueue являются Objective-C классы, которые делают аналогичную вещь. NSOperation был введен первым, но с 10.6 и iOS 4,NSOperationQueue и друзья внутренне реализованы с помощью GCD.

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

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

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

в соответствии с мой ответ на соответствующий вопрос, Я собираюсь не согласиться с BJ и предлагаю вам сначала взглянуть на GCD над NSOperation / NSOperationQueue, если последний не предоставляет то, что вам нужно, что GCD не делает.

перед GCD я использовал много NSOperations / NSOperationQueues в своих приложениях для управления параллелизмом. Однако, поскольку я начал использовать GCD на регулярной основе, я почти полностью заменил NSOperations и NSOperationQueues блоками и очереди отправки. Это произошло от того, как я использовал обе технологии на практике, и от профилирования, которое я выполнил на них.

во-первых, существует нетривиальное количество накладных расходов при использовании NSOperations и NSOperationQueues. Это объекты какао, и они должны быть выделены и освобождены. В приложении iOS, которое я написал, которое отображает трехмерную сцену со скоростью 60 кадров в секунду, я использовал NSOperations для инкапсуляции каждого отрисованного кадра. Когда я профилировал это, создание и демонтаж из этих NSOperations приходилось на значительную часть циклов процессора в запущенном приложении и замедляло работу. Я заменил их простыми блоками и последовательной очередью GCD, и эти накладные расходы исчезли, что привело к заметно лучшей производительности рендеринга. Это было не единственное место, где я заметил накладные расходы от использования NSOperations, и я видел это как на Mac, так и на iOS.

во-вторых, есть элегантность, чтобы блокировать на основе диспетчерского кода, который трудно сопоставить, когда используя NSOperations. Это так невероятно удобно, чтобы обернуть несколько строк кода в блок и отправить его для выполнения в последовательной или параллельной очереди, где создание пользовательского NSOperation или NSInvocationOperation для этого требуется гораздо больше кода поддержки. Я знаю, что вы можете использовать NSBlockOperation, но вы также можете отправить что-то в GCD. Обертывание этого кода в блоки, встроенные в соответствующую обработку в вашем приложении, приводит, на мой взгляд, к лучшей организации кода чем наличие отдельных методов или пользовательских NSOperations, которые инкапсулируют эти задачи.

NSOperations и NSOperationQueues по-прежнему имеют очень хорошее применение. GCD не имеет реальной концепции зависимостей, где NSOperationQueues может создавать довольно сложные графики зависимостей. Я использую NSOperationQueues для этого в нескольких случаях.

в целом, хотя я обычно выступаю за использование самого высокого уровня абстракции, который выполняет задачу, это один случай, когда я утверждаю, что API нижнего уровня GCD. Среди разработчиков iOS и Mac, с которыми я говорил об этом, подавляющее большинство предпочитают использовать GCD над NSOperations, если они не нацелены на версии ОС без поддержки (те, которые до iOS 4.0 и Snow Leopard).

GCD - это низкоуровневый API на основе C.
NSOperation и NSOperationQueue являются классами Objective-C.
NSOperationQueue является объективной оболочкой C над GCD. Если вы используете NSOperation, то вы неявно используете Grand Central Dispatch.

преимущество GCD над NSOperation:
я. реализации
Ибо GCD реализация очень легкий вес
NSOperationQueue - это сложный и тяжелые-вес

преимущества NSOperation над GCD:

я. Управление По Эксплуатации
вы можете приостановить, отменить, возобновить NSOperation

второй. Зависимости
вы можете установить зависимость между двумя NSOperations
операция не будет запущена, пока все ее зависимости не вернут true для finished.

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

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

когда идти на GCD или NSOperation
когда вы хотите больше контроля над очередью (все вышеперечисленное) используйте NSOperation и для простых случаев, когда вы хотите меньше накладных расходов (вы просто хотите сделать некоторую работу "в фоновом режиме" с очень небольшим количеством дополнительная работа) используйте GCD

ref:
https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http://nshipster.com/nsoperation/

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

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

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

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

также с NSOperation, KVO может быть возможно.

здесь это статья из Eschaton которые стоит прочитать.

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

ну, на основе предыдущего сообщения мы видим, что NSOperations имеет addDependency, так что вы можете поставить свою операцию в очередь один за другим последовательно.

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

преимущества NSQueueOperation перед GCD:

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

  2. легко отменить операцию, если она находится в очереди, ее можно остановить, если она запущена.

  3. вы можете определите максимальное число параллельных операций.

  4. вы можете приостановить операции, которые они находятся в очереди

  5. вы можете найти, сколько ожидающих операции в очереди.

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

преимущество NSOperation заключается в том, что (а) у вас есть реальный объект, на который вы можете отправлять сообщения, и (Б) что вы можете отменить NSOperation. Это не тривиально. Вам нужно подкласс NSOperation, вы должны написать свой код правильно, так что отмена и правильно завершая задачу оба работают правильно. Поэтому для простых вещей вы используете GCD, а для более сложных вещей вы создаете подкласс NSOperation. (Существуют подклассы NSInvocationOperation и NSBlockOperation, но все, что они делают, проще сделать с помощью GCD, поэтому нет никаких веских причин их использовать).

Ну, NSOperations-это просто API, построенный поверх Grand Central Dispatch. Поэтому, когда вы используете NSOperations, вы действительно все еще используете Grand Central Dispatch. Это просто, что NSOperations дают вам некоторые причудливые функции, которые вам могут понравиться. Вы можете сделать некоторые операции зависимыми от других операций, изменить порядок очередей после суммирования элементов и других подобных вещей. Фактически, ImageGrabber уже использует nsoperations и операционные очереди! ASIHTTPRequest использует их под капотом, и вы можете настроить очередь операций, которую он использует для другого поведения, если хотите. Так что же вы должны использовать? Какой смысл для вашего приложения. Для этого приложения это довольно просто, поэтому мы просто использовали Grand Central Dispatch напрямую, нет необходимости в причудливых функциях NSOperation. Но если вы нуждаетесь в них для вашего приложения, не стесняйтесь использовать его!