Я изучаю параллельное программирование для iOS. До сих пор я читал о NSOperation
/NSOperationQueue
и GCD
. Каковы причины использования NSOperationQueue
снова GCD
и наоборот?
Звучит как и то, GCD
и другое, NSOperationQueue
абстрагируясь от явного создания NSThreads
пользователя. Однако связь между этими двумя подходами мне не ясна, поэтому любые отзывы приветствуются!
ios
concurrency
grand-central-dispatch
nsoperation
nsoperationqueue
Воскресение понедельник
источник
источник
Ответы:
GCD
является низкоуровневым API на основе C, который позволяет очень просто использовать модель параллелизма на основе задач.NSOperation
иNSOperationQueue
классы Objective C, которые делают подобную вещь.NSOperation
был представлен первым, но по состоянию на 10.5 и iOS 2 ,NSOperationQueue
а друзья реализованы внутренне с помощьюGCD
.В общем, вы должны использовать самый высокий уровень абстракции, который соответствует вашим потребностям. Это означает, что вы обычно должны использовать
NSOperationQueue
вместоGCD
, если вам не нужно делать что-то, чтоNSOperationQueue
не поддерживает.Обратите внимание, что
NSOperationQueue
это не «тупая» версия GCD; на самом деле, есть много вещей, которые вы можете сделать очень просто,NSOperationQueue
которые требуют много работы с чистымGCD
. (Примеры: очереди с ограниченной пропускной способностью, которые одновременно выполняют только N операций; устанавливают зависимости между операциями. Обе очень простыеNSOperation
, очень сложныеGCD
.) Apple проделала тяжелую работу по использованию GCD для создания очень приятного объектно-ориентированного APINSOperation
. Воспользуйтесь их работой, если у вас нет причин не делать этого.Предостережение : с другой стороны, если вам действительно нужно отправить блок, и вам не нужны какие-либо дополнительные функциональные возможности, то
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. Заключение этого кода в блоки в соответствии с соответствующей обработкой в вашем приложении, на мой взгляд, приводит к лучшей организации кода, чем использование отдельных методов или пользовательских операций NSO, которые инкапсулируют эти задачи.
NSOperations и NSOperationQueues по-прежнему имеют очень хорошее применение. GCD не имеет реальной концепции зависимостей, где NSOperationQueues может создавать довольно сложные графы зависимостей. Я использую NSOperationQueues для этого в нескольких случаях.
В целом, хотя я обычно выступаю за использование самого высокого уровня абстракции, который выполняет задачу, это один из случаев, когда я спорю о низкоуровневом API GCD. Среди разработчиков iOS и Mac, с которыми я говорил об этом, подавляющее большинство предпочитают использовать GCD поверх NSOperations, если они не нацелены на версии ОС без поддержки этого (те, что до iOS 4.0 и Snow Leopard).
источник
GCD
является низкоуровневым C-API.NSOperation
иNSOperationQueue
являются классами Objective-C.NSOperationQueue
является объективной оберткой C надGCD
. Если вы используете NSOperation, то вы неявно используете Grand Central Dispatch.Преимущество GCD перед NSOperation:
i. Реализация
Для
GCD
реализации очень легкийNSOperationQueue
, сложный и тяжелыйПреимущества NSOperation перед GCD:
я. Control On Operation
вы можете приостановить, отменить, возобновить
NSOperation
II. Зависимости, которые
вы можете установить зависимость между двумя
NSOperations
операциями, не будут запущены, пока все ее зависимости не вернут true для завершения.
III. State of Operation
может отслеживать состояние операции или очереди операций. готов, выполняется или закончен
внутривенно Максимальное количество операций,
вы можете указать максимальное количество операций в очереди, которые могут выполняться одновременно
Когда следует использовать Go
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/
источник
Другой причиной, по которой NSOperation предпочтительнее GCD, является механизм отмены NSOperation. Например, приложение, такое как 500px, которое показывает десятки фотографий, использует NSOperation, мы можем отменить запросы невидимых ячеек изображения, когда мы прокручиваем представление таблицы или представление коллекции, это может значительно повысить производительность приложения и уменьшить объем памяти. GCD не может легко поддержать это.
Также с NSOperation KVO может быть возможным.
Вот статья из Eschaton, которую стоит прочитать.
источник
NSOperation
, так какNSURLSessionTask.cancel
иNSURLSession.invalidateAndCancel
предоставляют эту функциональность. В общем,NSURLSession
предоставляет некоторые функциональные возможностиNSOperationQueue
, а такжеNSURLSessionTask
предоставляет некоторые функциональные возможностиNSOperation
GCD действительно более низкого уровня, чем NSOperationQueue, его главное преимущество заключается в том, что его реализация очень легкая и ориентирована на алгоритмы и производительность без блокировок.
NSOperationQueue предоставляет средства, которые недоступны в GCD, но они имеют нетривиальную стоимость, реализация NSOperationQueue сложна и тяжела, включает в себя много блокировок и использует GCD изнутри только минимальным образом.
Если вам нужны средства, предоставляемые NSOperationQueue, во что бы то ни стало, используйте его, но если GCD достаточно для ваших нужд, я бы порекомендовал использовать его напрямую для повышения производительности, значительного снижения затрат на ЦП и энергопотребление и большей гибкости.
источник
И NSQueueOperations, и GCD позволяют выполнять сложные вычислительные задачи в фоновом режиме в отдельных потоках, освобождая основную программу приложения UI.
Итак, основываясь на предыдущем посте, мы видим, что NSOperations имеет addDependency, чтобы вы могли последовательно ставить свои операции в очередь.
Но я также читал о последовательных очередях GCD, которые вы можете создавать для запуска своих операций в очереди с помощью dispatch_queue_create. Это позволит последовательно выполнять набор операций один за другим.
NSQueueOperation Преимущества перед GCD:
Он позволяет добавить зависимость и позволяет удалить зависимость, поэтому для одной транзакции вы можете запускать последовательно с использованием зависимости, а для другой транзакции - одновременно, в то время как GCD не позволяет работать таким образом.
Операцию легко отменить, если она находится в очереди, ее можно остановить, если она выполняется.
Вы можете определить максимальное количество одновременных операций.
Вы можете приостановить операцию, которую они находятся в очереди
Вы можете найти сколько ожидающих операций в очереди.
источник
GCD очень прост в использовании - если вы хотите сделать что-то в фоновом режиме, все, что вам нужно сделать, это написать код и отправить его в фоновую очередь. Делать то же самое с NSOperation - это много дополнительной работы.
Преимущество NSOperation заключается в том, что (a) у вас есть реальный объект, на который вы можете отправлять сообщения, и (b) вы можете отменить NSOperation. Это не тривиально. Вам необходимо создать подкласс NSOperation, вы должны правильно написать свой код, чтобы отмена и правильное завершение задачи работали правильно. Так что для простых вещей вы используете GCD, а для более сложных вещей вы создаете подкласс NSOperation. (Существуют подклассы NSInvocationOperation и NSBlockOperation, но все, что они делают, легче сделать с помощью GCD, поэтому нет веских оснований для их использования).
источник
Ну, NSOperations - это просто API, созданный поверх Grand Central Dispatch. Поэтому, когда вы используете NSOperations, вы все еще используете Grand Central Dispatch. Просто NSOperations дает вам некоторые интересные функции, которые вам могут понравиться. Вы можете сделать некоторые операции зависимыми от других операций, изменить порядок очередей после добавления элементов и тому подобное. Фактически, ImageGrabber уже использует NSOperations и очереди операций! ASIHTTPRequest использует их под капотом, и вы можете настроить очередь операций, которую он использует, для другого поведения, если хотите. Так что вы должны использовать? Все, что имеет смысл для вашего приложения. Для этого приложения это довольно просто, поэтому мы просто использовали Grand Central Dispatch напрямую, без необходимости в необычных функциях NSOperation. Но если они нужны для вашего приложения, не стесняйтесь использовать его!
источник