NSOperation y Grand Central Dispatch
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
over GCD
y viceversa?
Suena como ambas cosas GCD
y NSOperationQueue
abstrae la creación explícita de NSThreads
por parte del usuario. Sin embargo, la relación entre los dos enfoques no está clara para mí, por lo que agradezco cualquier comentario.
GCD
es una API basada en C de bajo nivel que permite un uso muy sencillo 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.5 y iOS 2 , NSOperationQueue
y los amigos se implementan internamente usando GCD
.
En general, debes utilizar el nivel más alto de abstracción que se adapte a tus necesidades. Esto significa que normalmente deberías usar NSOperationQueue
en lugar de GCD
, a menos que necesites hacer algo que NSOperationQueue
no sea compatible.
Tenga en cuenta que NSOperationQueue
no es una versión "simplificada" de GCD; de hecho, hay muchas cosas que puedes hacer de forma muy sencilla NSOperationQueue
y que requieren mucho trabajo con pure GCD
. (Ejemplos: colas con ancho de banda limitado 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 arduo trabajo de aprovechar GCD para crear una API muy agradable compatible con objetos con NSOperation
. Aprovecha su trabajo a menos que tengas un motivo para no hacerlo.
Advertencia : por otro lado, si realmente solo necesita enviar un bloque y no necesita ninguna de las funciones adicionales que NSOperationQueue
proporciona, no hay nada de malo en usar GCD. Solo asegúrese de que sea la herramienta adecuada para el trabajo.
De acuerdo con mi respuesta a una pregunta relacionada , no estaré de acuerdo con BJ y le sugiero que primero mire GCD en lugar de NSOperation/NSOperationQueue, a menos que este último proporcione algo que necesita y que GCD no ofrece.
Antes de GCD, usaba muchas NSOperations/NSOperationQueues dentro de mis aplicaciones para administrar la concurrencia. Sin embargo, desde que comencé a usar GCD de forma regular, reemplacé casi por completo 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 a la elaboración de perfiles que he realizado sobre ellas.
En primer lugar, existe una cantidad no trivial de gastos generales cuando se utilizan NSOperations y NSOperationQueues. Estos son objetos Cocoa y es necesario asignarlos y desasignarlos. En una aplicación de iOS que escribí y que representa una escena 3D a 60 FPS, estaba usando NSOperations para encapsular cada cuadro renderizado. Cuando perfilé esto, la creación y el desmantelamiento de estas NSOperations representaban una parte importante de los ciclos de CPU en la aplicación en ejecución y ralentizaban las cosas. Los reemplacé con bloques simples y una cola serial GCD, y esa sobrecarga desapareció, lo que llevó a un rendimiento de renderizado notablemente mejor. Este no fue el único lugar donde noté una sobrecarga al usar NSOperations, y lo he visto tanto en Mac como en iOS.
En segundo lugar, el código de distribución basado en bloques tiene una elegancia que es difícil de igualar cuando se utiliza NSOperations. Es increíblemente conveniente empaquetar algunas líneas de código en un bloque y enviarlo para que se ejecute en una cola en serie o simultánea, donde crear una NSOperation o NSInvocationOperation personalizada para hacer esto requiere mucho más código de soporte. Sé que puedes usar NSBlockOperation, pero entonces también podrías enviar algo a GCD. En mi opinión, empaquetar este código en bloques en línea con el procesamiento relacionado en su aplicación conduce 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 dependencia bastante complejos. Utilizo NSOperationQueues para esto en algunos casos.
En general, aunque normalmente defiendo el uso del nivel más alto de abstracción que cumpla 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 elige usar GCD en lugar de NSOperations a menos que se dirijan a versiones del sistema operativo sin soporte (aquellas anteriores a iOS 4.0 y Snow Leopard).
GCD
es una API basada en C de bajo nivel.
NSOperation
y NSOperationQueue
son clases Objective-C.
NSOperationQueue
Se acabó el envoltorio del objetivo GCD
C. Si está utilizando NSOperation, implícitamente está utilizando Grand Central Dispatch.
Ventaja de GCD sobre NSOperation:
i. implementación
Para GCD
la implementación es muy liviana
NSOperationQueue
es compleja y pesada
Ventajas de NSOperation sobre GCD:
i. Control En funcionamiento
puede pausar, cancelar, reanudar unaNSOperation
ii. Dependencias
Puede configurar una dependencia entre dos NSOperations
operaciones que no se iniciarán hasta que todas sus dependencias devuelvan verdadero para finalizar.
III. State of Operation
puede monitorear el estado de una operación o 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 se pueden ejecutar simultáneamente
Cuándo elegir GCD
oNSOperation
cuándo desea tener más control sobre el uso de la cola (todo lo mencionado anteriormente) NSOperation
y para casos simples en los que desea menos gastos generales (solo desea trabajar un poco "en segundo plano" con muy poco trabajo adicional) useGCD
ref:
https://cocoacasts.com/choosing-between-nsoperative-and-grand-central-dispatch/
http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperativequeue.html
http //nshipster.com/nsoperación/
Otra razón para preferir NSOperation a GCD es el mecanismo de cancelación de NSOperation. Por ejemplo, una aplicación como 500px que muestra docenas de fotos, usando NSOperation podemos cancelar solicitudes de celdas de imágenes invisibles cuando nos desplazamos por la vista de tabla o la vista de colección, esto puede mejorar en gran medida el rendimiento de la aplicación y reducir el uso de memoria. GCD no puede soportar esto fácilmente.
También con NSOperation, KVO puede ser posible.
Aquí hay un artículo de Eschaton que vale la pena leer.
De hecho, GCD es de nivel inferior que NSOperationQueue, su principal ventaja es que su implementación es muy liviana y se centra en algoritmos y rendimiento sin bloqueos.
NSOperationQueue proporciona funciones 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 mínima.
Si necesita las funciones proporcionadas por NSOperationQueue, úselas por todos los medios, pero si GCD es suficiente para sus necesidades, recomendaría usarlo directamente para obtener un mejor rendimiento, un costo de energía y CPU significativamente menor y más flexibilidad.