NSOperation vs Grand Central Dispatch


Estoy aprendiendo sobre programación concurrente para iOS. Hasta ahora he leído acerca de NSOperation/NSOperationQueue y GCD. ¿Cuáles son las razones para usar NSOperationQueue sobre GCD y viceversa?

Suena como que tanto GCD como NSOperationQueue abstraen la creación explícita de NSThreads del usuario. Sin embargo, la relación entre los dos enfoques no está claro para mí por lo que cualquier retroalimentación a apreciado!

Author: SundayMonday, 2012-04-29

8 answers

GCD es una API basada en C de bajo nivel que permite el uso muy simple de un modelo de concurrencia basado en tareas. NSOperation y NSOperationQueue son clases Objective-C que hacen algo similar. NSOperation se introdujo primero, pero a partir de 10.6 e iOS 4, NSOperationQueue y amigos se implementan internamente usando GCD.

En general, debe usar el nivel más alto de abstracción que se adapte a sus necesidades. Esto significa que normalmente debes usar NSOperationQueue en lugar de GCD, a menos que necesites hacer algo que NSOperationQueue no apoyo.

Tenga en cuenta que NSOperationQueue no es una versión "tonta" de GCD; de hecho, hay muchas cosas que se pueden hacer muy simplemente con NSOperationQueue que requieren mucho trabajo con pure GCD. (Ejemplos: colas de ancho de banda restringido que solo ejecutan N operaciones a la vez; establecer dependencias entre operaciones. Ambos muy simples con NSOperation, muy difíciles con GCD.) Apple ha hecho el duro trabajo de aprovechar GCD para crear una API muy agradable para objetos con NSOperation. Aproveche su trabajo a menos que tengas una razón para no hacerlo.

Advertencia: Por otro lado, si realmente solo necesita enviar un bloque, y no necesita ninguna de las funcionalidades adicionales que NSOperationQueue proporciona, no hay nada de malo en usar GCD. Solo asegúrate de que sea la herramienta adecuada para el trabajo.

 481
Author: BJ Homer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-10 19:40:37

En línea con mi respuesta a una pregunta relacionada, voy a estar en desacuerdo con BJ y sugerirle que primero mire GCD sobre NSOperation / NSOperationQueue, a menos que este último proporcione algo que usted necesita que GCD no.

Antes de GCD, usé muchas NSOperations / NSOperationQueues dentro de mis aplicaciones para administrar la concurrencia. Sin embargo, desde que empecé a usar GCD de forma regular, he reemplazado casi por completo NSOperations y NSOperationQueues con bloques y despacho cola. Esto ha venido de cómo he utilizado ambas tecnologías en la práctica, y de los perfiles que he realizado en ellas.

Primero, hay una cantidad no trivial de sobrecarga cuando se usan NSOperations y NSOperationQueues. Estos son objetos de Cacao, y necesitan ser asignados y desasignados. En una aplicación iOS que escribí que renderiza una escena 3D a 60 FPS, estaba usando NSOperations para encapsular cada fotograma renderizado. Cuando perfilé esto, la creación y destrucción de estos NSOperations era responsable de una parte significativa de los ciclos de CPU en la aplicación en ejecución, y estaba ralentizando las cosas. Reemplacé estos con bloques simples y una cola de serie GCD, y esa sobrecarga desapareció, lo que llevó a un rendimiento de renderizado notablemente mejor. Este no fue el único lugar donde noté la sobrecarga del uso de NSOperations, y he visto esto tanto en Mac como en iOS.

Segundo, hay una elegancia en el código de despacho basado en bloques que es difícil de igualar cuando se usa NSOperations. Es increíblemente conveniente envolver unas pocas líneas de código en un bloque y enviarlo para que se realice en una cola serial o concurrente, donde la creación de una NSOperation personalizada o NSInvocationOperation para hacer esto requiere mucho más código de soporte. Sé que puedes usar una NSBlockOperation, pero también podrías enviar algo a GCD entonces. Empaquetar este código en bloques en línea con el procesamiento relacionado en su aplicación conduce en mi opinión a una mejor organización del código que tener métodos separados o NSOperations personalizados que encapsulan estas tareas.

NSOperations y NSOperationQueues todavía tienen muy buenos usos. GCD no tiene un concepto real de dependencias, donde NSOperationQueues puede configurar gráficos de dependencias bastante complejos. Utilizo NSOperationQueues para esto en un puñado de casos.

En general, aunque suelo abogar por el uso del nivel más alto de abstracción que logra la tarea, este es un caso en el que defiendo la API de nivel inferior de GCD. Entre los desarrolladores de iOS y Mac con los que he hablado sobre esto, la gran mayoría opta por usar GCD en lugar de NSOperations a menos que estén apuntando a versiones del sistema operativo sin soporte para ello (los anteriores a iOS 4.0 y Snow Leopard).

 348
Author: Brad Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:35

GCD es una API basada en C de bajo nivel.
NSOperation y NSOperationQueue son clases Objective-C.
NSOperationQueue es la envoltura del objetivo C sobre GCD. Si está utilizando NSOperation, entonces está utilizando implícitamente Grand Central Dispatch.

Ventaja de GCD sobre NSOperation:
i. aplicación
Para GCD la implementación es muy ligera
NSOperationQueue es complejo y pesado

Ventajas de NSOperation sobre GCD:

i. Control De La Operación
puede Pausar, Cancelar, Reanudar un NSOperation

ii. Dependencias
puede configurar una dependencia entre dos NSOperations
la operación no se iniciará hasta que todas sus dependencias devuelvan true para finished.

iii. Estado de funcionamiento
puede monitorear el estado de una operación o cola de operación. listo, ejecutándose o terminado

iv. Número máximo de operaciones
puede especificar el número máximo de operaciones en cola que pueden ejecutarse simultáneamente

Cuando ir para GCD o NSOperation
cuando desee más control sobre la cola (todo lo mencionado anteriormente) use NSOperation y para casos simples en los que desea menos gastos generales (solo desea hacer un poco de trabajo "en segundo plano" con muy poco trabajo adicional) uso 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 /

 61
Author: Sangram S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-15 21:36:14

GCD es de hecho de menor nivel que NSOperationQueue, su principal ventaja es que su implementación es muy liviana y se centra en algoritmos y rendimiento sin bloqueos.

NSOperationQueue proporciona instalaciones que no están disponibles en GCD, pero tienen un costo no trivial, la implementación de NSOperationQueue es compleja y pesada, implica mucho bloqueo y usa GCD internamente solo de una manera muy mínima.

Si necesita las instalaciones proporcionadas por NSOperationQueue por todos los medios úselo, pero si GCD es suficiente para sus necesidades, recomendaría usarlo directamente para un mejor rendimiento, un costo significativamente menor de CPU y energía y más flexibilidad.

 33
Author: das,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-03 16:13:51

Otra razón para preferir NSOperation sobre GCD es el mecanismo de cancelación de NSOperation. Por ejemplo, una aplicación como 500px que muestra docenas de fotos, use NSOperation podemos cancelar las solicitudes de celdas de imagen invisibles cuando nos desplazamos a la vista de tabla o a la vista de colección, esto puede mejorar en gran medida el rendimiento de la aplicación y reducir la huella de memoria. GCD no puede soportar esto fácilmente.

También con NSOperation, KVO puede ser posible.

Aquí es un artículo de Eschaton que vale la pena lectura.

 33
Author: evanchin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-19 20:21:45

Tanto NSQueueOperations como GCD permiten ejecutar tareas de cálculo pesadas en segundo plano en subprocesos separados al liberar la banda de rodadura principal de la aplicación de interfaz de usuario.

Bueno, basado en el post anterior vemos que NSOperations tiene addDependency para que pueda poner en cola su operación una tras otra secuencialmente.

Pero también he leído sobre colas serie GCD que puede crear ejecutar sus operaciones en la cola utilizando dispatch_queue_create. Esto permitirá ejecutar un conjunto de operaciones una tras otra en un de manera secuencial.

NSQueueOperation Advantages over GCD:

  1. Permite agregar dependencia y le permite eliminar dependencia para que para una transacción pueda ejecutar secuencial usando dependencia y para otra transacción ejecutar simultáneamente mientras GCD no permite correr de esta manera.

  2. Es fácil cancelar una operación si está en la cola se puede detener si se está ejecutando.

  3. Puede definir el número máximo de concurrentes operación.

  4. Puede suspender la operación que están en cola

  5. Puede encontrar cuántas operaciones pendientes hay en la cola.

 23
Author: Shashi3456643,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-31 01:43:44

GCD es muy fácil de usar: si desea hacer algo en segundo plano, todo lo que necesita hacer es escribir el código y enviarlo a una cola en segundo plano. Hacer lo mismo con NSOperation es mucho trabajo adicional.

La ventaja de NSOperation es que (a) tiene un objeto real al que puede enviar mensajes, y (b) que puede cancelar una NSOperation. Eso no es trivial. Necesitas subclase NSOperation, tienes que escribir tu código correctamente para que la cancelación y terminar correctamente una tarea ambos funcionan correctamente. Así que para cosas simples se usa GCD, y para cosas más complicadas se crea una subclase de NSOperation. (Hay subclases NSInvocationOperation y NSBlockOperation, pero todo lo que hacen es más fácil de hacer con GCD, por lo que no hay una buena razón para usarlos).

 5
Author: gnasher729,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-06 00:41:19

Bueno, NSOperations son simplemente una API construida sobre Grand Central Dispatch. Así que cuando estás usando NSOperations, todavía estás usando Grand Central Dispatch. Es solo que NSOperations le dan algunas características de lujo que le pueden gustar. Puede hacer que algunas operaciones dependan de otras operaciones, reordenar las colas después de sus elementos sumbit y otras cosas por el estilo. De hecho, ImageGrabber ya está utilizando NSOperations y colas de operación! ASIHTTPRequest los utiliza bajo el capó, y usted puede configurar la cola de operaciones que utiliza para un comportamiento diferente si lo desea. Entonces, ¿cuál deberías usar? Lo que tenga sentido para tu aplicación. Para esta aplicación es bastante simple, así que solo usamos Grand Central Dispatch directamente, sin necesidad de las características de lujo de NSOperation. Pero si los necesita para su aplicación, no dude en usarlo!

 3
Author: Ankul Gaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-13 11:40:15