NSOperation vs Grand Central Dispatch

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

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

II. зависимости
вы можете настроить зависимость между двумя NSOperations
операция не начнется, пока все ее зависимости не вернутся к завершению.

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

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

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

ссылка
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/

Ответ 4

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

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

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

Ответ 5

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

Также с NSOperation возможно KVO.

Здесь - статья из Eschaton, которую стоит прочитать.

Ответ 6

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

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

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

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

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

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

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

  • Вы можете приостановить действие, которое они находятся в очереди

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

Ответ 7

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

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

Ответ 8

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