ios concurrency grand-central-dispatch nsoperation nsoperationqueue

ios - NSOperation vs Grand Central Dispatch



concurrency grand-central-dispatch (8)

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

Suena como GCD y NSOperationQueue abstraen la creación explícita de NSThreads del usuario. Sin embargo, la relación entre los dos enfoques no está clara para mí, ¡así que cualquier comentario que aprecie!


Bueno, las NSOperations son simplemente una API construida sobre Grand Central Dispatch. Por lo tanto, cuando utiliza las NSOperations, realmente sigue utilizando Grand Central Dispatch. Es solo que las NSOperations te ofrecen algunas funciones extravagantes que te pueden gustar. Puede hacer que algunas operaciones dependan de otras operaciones, reordenar las colas después de agregar elementos y otras cosas por el estilo. De hecho, ImageGrabber ya está utilizando las operaciones NSO y las colas de operación. ASIHTTPRequest los usa bajo el capó, y puede configurar la cola de operaciones que utiliza para diferentes comportamientos si lo desea. Entonces, ¿cuál debería 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 funciones de lujo de NSOperation. Pero si los necesita para su aplicación, ¡siéntase libre de usarla!


De acuerdo con mi respuesta a una pregunta relacionada , no estaré de acuerdo con BJ y le sugeriré que primero vea GCD sobre NSOperation / NSOperationQueue, a menos que este último proporcione algo que necesita que GCD no.

Antes de GCD, usé muchas NSOperations / NSOperationQueues dentro de mis aplicaciones para administrar la concurrencia. Sin embargo, desde que comencé a usar GCD de forma regular, he reemplazado casi completamente NSOperations y NSOperationQueues con bloques y colas de envío. Esto se debe a cómo he utilizado ambas tecnologías en la práctica y al perfil que he realizado en ellas.

Primero, hay una cantidad no trivial de gastos generales cuando se utilizan NSOperations y NSOperationQueues. Estos son objetos de cacao, y deben ser asignados y desasignados. En una aplicación para iOS que escribí que representa una escena 3D a 60 FPS, estaba usando NSOperations para encapsular cada cuadro renderizado. Cuando hice un perfil de esto, la creación y el desmontaje de estas NSOperations representaban una parte significativa de los ciclos de la CPU en la aplicación en ejecución, y estaba ralentizando las cosas. Los reemplacé con bloques simples y una cola serie GCD, y esa sobrecarga desapareció, lo que llevó a un rendimiento de renderización notablemente mejor. Este no fue el único lugar donde noté la sobrecarga por el uso de NSOperations, y lo he visto tanto en Mac como en iOS.

En segundo lugar, hay una elegancia en el código de despacho basado en bloques que es difícil de igualar cuando se utilizan las operaciones NSO. Es increíblemente conveniente envolver unas pocas líneas de código en un bloque y enviarlo para que se realice en una cola en serie o concurrente, donde crear un NSOperation personalizado o NSInvocationOperation para hacer esto requiere mucho más código de soporte. Sé que puedes usar un NSBlockOperation, pero entonces podrías estar enviando algo a GCD. Envolver 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 operaciones NSO personalizadas 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 dependencia bastante complejos. Utilizo NSOperationQueues para esto en un puñado de casos.

En general, aunque generalmente abogo por el uso del nivel más alto de abstracción que realiza la tarea, este es un caso en el que defiendo la API de bajo nivel de GCD. Entre los desarrolladores de iOS y Mac con los que he hablado sobre esto, la gran mayoría opta por usar GCD sobre NSOperations a menos que estén dirigidos a versiones de SO sin soporte (las anteriores a iOS 4.0 y Snow Leopard).


De hecho, GCD es un nivel más bajo que NSOperationQueue, su principal ventaja es que su implementación es muy liviana y se enfoca en algoritmos y rendimiento sin bloqueo.

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

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


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 en una cola de fondo. 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 operación NSO. Eso no es trivial. Debe subclasificar NSOperation, debe escribir su código correctamente para que la cancelación y la finalización correcta de una tarea funcionen correctamente. Por lo tanto, para cosas simples utiliza GCD y para cosas más complicadas crea una subclase de NSOperation. (Hay subclases NSInvocationOperation y NSBlockOperation, pero todo lo que hacen es más fácil hacerlo con GCD, por lo que no hay una buena razón para usarlas).


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 solicitudes de celdas de imagen invisibles cuando nos desplazamos por la vista de tabla o colección, esto puede mejorar mucho el rendimiento de la aplicación y reducir el espacio de memoria. GCD no puede soportar esto fácilmente.

También con NSOperation, KVO puede ser posible.

Here hay un artículo de Eschaton que vale la pena leer.


Tanto NSQueueOperations como GCD permiten ejecutar tareas pesadas de cómputo en segundo plano en subprocesos separados al liberar la Pisada principal de la aplicación UI.

Bueno, según la publicación anterior, vemos que NSOperations tiene addDependency para que pueda poner en cola su operación una tras otra de forma secuencial.

Pero también leí acerca de las colas en serie de GCD que puedes crear, ejecuta tus operaciones en la cola usando dispatch_queue_create. Esto permitirá ejecutar un conjunto de operaciones una tras otra de manera secuencial.

Ventajas de NSQueueOperation sobre GCD:

  1. Permite agregar dependencia y le permite eliminar la dependencia, por lo que para una transacción puede ejecutar la secuencia de uso secuencial y para otra transacción simultánea, mientras que GCD no permite que se ejecute 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 operaciones concurrentes.

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

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


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

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

Ventajas de NSOperation sobre GCD:

yo. Control de funcionamiento
puede pausar, cancelar, reanudar una NSOperation

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

iii. Estado de operación
Puede monitorear el estado de una operación o la cola de operaciones. listo, ejecutando 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

Cuándo 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 quiera menos gastos generales (solo quiere hacer un poco de trabajo "en el fondo" con muy poco trabajo adicional) use GCD

árbitro:
cocoacasts.com/… http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http://nshipster.com/nsoperation/


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

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

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

Advertencia : por otro lado, si realmente solo necesita enviar un bloque y no necesita ninguna de las funciones adicionales que proporciona NSOperationQueue , no hay nada de malo en usar GCD. Sólo asegúrese de que sea la herramienta adecuada para el trabajo.