29

referencia de Grand Central Dispatch de Apple dice:¿Por qué debería elegir GCD sobre NSOperation y bloques para aplicaciones de alto nivel?

" ... si la aplicación necesita para operar a nivel Unix del sistema, por ejemplo , si se necesita manipular los descriptores de fichero, Mach puertos, señales o temporizadores. GCD no está restringido a las aplicaciones de nivel de sistema , pero antes de usarlo para aplicaciones de nivel superior, debería considerar si una funcionalidad similar proporcionada en Cocoa (a través de NSOperation y objetos de bloque) sería más fácil de usar o más apropiado para sus necesidades. ".

http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

realidad no puedo pensar en situaciones, para aplicaciones de alto nivel, en el que el uso de GCD es obligatoria y NSOperation podía/no debe ser utilizado.

¿Alguna idea?

+0

https: // cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ – Masih

Respuesta

50

El punto que se hace aquí es el mismo que Chris Hanson afirma en su artículo "When to use NSOperation vs. GCD":

La respuesta sencilla es una guía general para todas las aplicaciones desarrollo:

Utilice siempre el la abstracción de más alto nivel disponible para usted, y deje caer hasta las abstracciones de nivel inferior cuando la medición muestre que son necesarios.

En este caso particular, significa que cuando se escriben aplicaciones Cocoa , generalmente debe usar NSOperation en lugar de usando GCD directamente. No debido a una diferencia en la eficiencia, pero porque NSOperation proporciona una abstracción de nivel superior encima de los mecanismos de GCD.

En general, estoy de acuerdo con esto.NSOperation y NSOperationQueue brindan soporte para dependencias y uno o dos aspectos más que los bloques y colas de GCD no tienen, y abstraen los detalles de nivel inferior de cómo se implementan las operaciones simultáneas. Si necesita esa funcionalidad, NSOperation es una muy buena forma de hacerlo.

Sin embargo, después de trabajar con ambos, me he encontrado reemplazando todo mi código basado en NSOpection con bloques GCD y colas. He hecho esto por dos razones: hay una sobrecarga significativa al usar NSOperation para acciones frecuentes, y creo que mi código es más limpio y más descriptivo cuando uso bloques GCD. El primer motivo proviene de la creación de perfiles en mis aplicaciones, donde descubrí que el proceso de asignación y desasignación de objetos NSOperation requería una cantidad significativa de recursos de CPU cuando se trata de acciones pequeñas y frecuentes, como renderizar un marco de OpenGL ES en la pantalla. Los bloques GCD eliminaron por completo esa sobrecarga, lo que permitió mejoras significativas en el rendimiento.

La segunda razón es más subjetiva, pero creo que mi código es más limpio cuando se usan bloques que NSOperations. La captura rápida del alcance permitido por un bloque y la naturaleza en línea de ellos hacen que haya menos código, porque no es necesario crear subclases NSOperation personalizadas o paquetes de parámetros para pasar a la operación, y un código más descriptivo en mi opinión, porque puede colocar el código para que se ejecute en una cola en el punto donde se dispara.

Una vez más, es una cuestión de preferencia, pero he descubierto que estoy usando GCD más, incluso en aplicaciones de Cocoa abstractas.

+0

NSOperationQueue ahora es capaz de usar cierres. ¿Debería esta respuesta estar (ligeramente) actualizada? Además, ¿hay alguna posibilidad de que NSOperation se haya optimizado en los últimos 5 años para reducir la sobrecarga que encontró? –

+0

Debo agregar que terminé haciendo exactamente lo contrario: después de años de usar GCD directamente, cambiar a NSOperationQueue fue una bocanada de aire fresco. Mi comportamiento de 'puesta en cola' está bien definido ahora, y tengo control total sobre las operaciones concurrentes máximas. También es más fácil cancelar operaciones en ejecución y reemplazarlas por otras nuevas, lo que da como resultado un comportamiento bien definido. Todavía uso GCD para operaciones de sincronización simple, pero he cambiado a NSOperationQueue para mis necesidades de cola serie/asíncrona. – strangetimes

+0

Upvoted para obtener una buena explicación. – user3182143

4

Bueno, NSOperation no tiene equivalentes para dispatch_source_t, dispatch_io, dispatch_data_t, dispatch_semaphore_t, etc ... También es algo más alto.

Por otro lado, libdispatch no tiene equivalentes a dependencias de operación, prioridades de operación (las prioridades de cola son algo diferentes) o KVO en las operaciones.

+1

'NSOperation' ahora se construye encima de' GCD', así que a menos que haya algo en uno que necesite que no esté en el otro no existe eso a favor del otro. – hypercrypt

+1

Todavía requiere asignaciones de objetos para operaciones, entre otras complejidades. Para el enhebrado de grano extremadamente fino que en realidad puede ser una sobrecarga significativa. Sí, he medido esto; sí, es crítico para algunos de mi código. El ajuste de GCD de NSOperation no es del todo el mapeo directo que uno podría esperar, ya que necesita soportar dependencias, KVO y prioridades. –

+0

Tiene razón, también he visto una sobrecarga significativa al usar NSOperation para acciones que se producen con frecuencia donde no veo eso con los bloques de GCD. La asignación/desasignación de objetos puede ser muy costosa en esos casos, por lo que GCD puede ser más apropiado. –

0

En realidad, he estado leyendo todo sobre esto, y estoy seguro de que llegará como saber sorpresa, las opiniones difieren.

No puedo pensar en un caso en el que tengas que usar GCD en NSOperation, pero eso no significa que ese caso no exista. Yo, sin embargo, estoy de acuerdo con un sentimiento general en términos de codificación de mejores prácticas:

Si tiene un par de herramientas que se adapten al trabajo (y en este caso, tiene NSOperation frente a un bloque GCD), utilice clase con el más alto nivel de abstracción (es decir, el nivel más alto API). No solo es normalmente más fácil de usar/menos código, sino que también se beneficiará de posibles mejoras futuras introducidas en las API de nivel superior.

13
  • Prefiero GCD donde tarea no es mucho más complejo y un rendimiento óptimo de la CPU se requiere.
  • Prefiere NSOperationQueue donde la tarea es compleja y requiere cancelar o suspender un bloque y administración de la dependencia.

GCD es una forma ligera de representar unidades de trabajo que se ejecutarán al mismo tiempo. Usted no programa estas unidades de trabajo; el sistema se encarga de la programación para usted. Agregar dependencia entre bloques puede ser un dolor de cabeza. ¡Cancelar o suspender un bloque crea trabajo adicional para usted como desarrollador!

NSOperation y NSOperationQueue agregan un poco de sobrecarga adicional en comparación con GCD, pero puede agregar dependencia entre varias operaciones. Puede reutilizar, cancelar o suspender operaciones. NSOperation es compatible con Key-Value Observation (KVO); por ejemplo, puede hacer que un inicio de NSOperation escuche NSNotificationCenter.

Para una explicación detallada, consulte esta pregunta: NSOperation vs Grand Central Dispatch

1

Hay dos cosas que NSOperationQueue puede hacer que GCD no hace: El menor es dependencias (añadir una operación para una cola, pero decirle que sólo se ejecutará cuando ciertas otras operaciones están terminadas), y el más grande es que NSOperation le da un objeto que puede recibir mensajes mientras la tarea se está ejecutando, a diferencia de GCD que tiene bloques que no pueden recibir mensajes excepto de una manera muy limitada. O necesita estas dos características o no. Si no lo hace, usar GCD es muchísimo más fácil de usar.

Es por eso que los ejemplos útiles de NSOperation son siempre bastante complejos. Si fueran fáciles, usarías GCD en su lugar. Por lo general, crea una subclase de NSOperation, que será una gran cantidad de trabajo, o use una que otra persona haya creado.

Cuestiones relacionadas