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 ambos GCD
y NSOperationQueue
abstrae la creación explícita NSThreads
del usuario. Sin embargo, la relación entre los dos enfoques no está clara para mí, por lo que cualquier comentario será apreciado.
ios
concurrency
grand-central-dispatch
nsoperation
nsoperationqueue
Domingo Lunes
fuente
fuente
Respuestas:
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
yNSOperationQueue
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 usandoGCD
.En general, debe usar el nivel más alto de abstracción que se adapte a sus necesidades. Esto significa que generalmente debe usar en
NSOperationQueue
lugar deGCD
, a menos que necesite hacer algo queNSOperationQueue
no sea compatible.Tenga en cuenta que
NSOperationQueue
no es una versión "tonta" de GCD; de hecho, hay muchas cosas que puedes hacer de manera muy simpleNSOperationQueue
que requieren mucho trabajo con pureGCD
. (Ejemplos: colas restringidas de ancho de banda que solo ejecutan N operaciones a la vez; establecer dependencias entre operaciones. Ambas muy simples conNSOperation
, muy difíciles conGCD
.) Apple ha hecho el trabajo duro de aprovechar GCD para crear una API amigable con los objetos muy agradableNSOperation
. 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
NSOperationQueue
proporciona, no hay nada de malo en usar GCD. Solo asegúrese de que sea la herramienta adecuada para el trabajo.fuente
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 necesita que GCD no.
Antes de GCD, utilicé muchas NSOperations / NSOperationQueues dentro de mis aplicaciones para gestionar la concurrencia. Sin embargo, desde que comencé a usar GCD de forma regular, he reemplazado casi por completo NSOperations y NSOperationQueues con bloques y colas de despacho. Esto ha venido de cómo he usado ambas tecnologías en la práctica, y del perfil que he realizado en ellas.
Primero, hay una cantidad de sobrecarga no trivial cuando se usan NSOperations y NSOperationQueues. Estos son objetos Cocoa, y deben asignarse y desasignarse. En una aplicación para iOS que escribí que renderiza una escena tridimensional a 60 FPS, estaba usando NSOperations para encapsular cada cuadro renderizado. Cuando hice un perfil de esto, la creación y el desmantelamiento de estas operaciones de NSO representaban una parte significativa de los ciclos de la 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 condujo a un rendimiento de representación notablemente mejor. Este no fue el único lugar donde noté gastos generales al usar NSOperations, y lo he visto tanto en Mac como en iOS.
En segundo lugar, hay una elegancia en el código de envío basado en bloques que es difícil de igualar cuando se usan 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 o NSInvocationOperation personalizada 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. 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 defiendo el uso del más alto nivel de abstracción que realiza 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 sobre NSOperations a menos que estén dirigidos a versiones de SO sin soporte para ellas (anteriores a iOS 4.0 y Snow Leopard).
fuente
GCD
es una API basada en C de bajo nivel.NSOperation
yNSOperationQueue
son clases de Objective-C.NSOperationQueue
es el envoltorio objetivo C terminadoGCD
. Si está utilizando NSOperation, está utilizando implícitamente Grand Central Dispatch.Ventaja de GCD sobre NSOperation:
i. implementación
Para la
GCD
implementación es muy ligero,NSOperationQueue
es complejo y pesadoVentajas de NSOperation sobre GCD:
yo. Control en funcionamiento
puede pausar, cancelar, reanudar un
NSOperation
ii. Las dependencias en las
que puede configurar una dependencia entre dos
NSOperations
operaciones no se iniciarán hasta que todas sus dependencias vuelvan verdaderas para finalizar.
iii) El estado de operación
puede monitorear el estado de una operación o una cola de operaciones. 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
Cuándo ir
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 sobrecarga (solo desea hacer un trabajo "en segundo plano" con muy poco trabajo adicional)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/
fuente
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, usa NSOperation, podemos cancelar las solicitudes de celdas de imagen invisibles cuando desplazamos la vista de tabla o 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í hay un artículo de Eschaton que vale la pena leer.
fuente
NSOperation
para esto, comoNSURLSessionTask.cancel
yNSURLSession.invalidateAndCancel
proporcionar esta funcionalidad. En general,NSURLSession
proporciona parte de la funcionalidad de unNSOperationQueue
, comoNSURLSessionTask
proporciona parte de la funcionalidad de unNSOperation
GCD es de hecho 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 pesada, implica mucho bloqueo y usa GCD internamente solo de manera mínima.
Si necesita las facilidades proporcionadas por NSOperationQueue, utilícelo por todos los medios, pero si GCD es suficiente para sus necesidades, recomendaría usarlo directamente para un mejor rendimiento, un costo de CPU y de energía significativamente menor y más flexibilidad.
fuente
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 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 secuencialmente.
Pero también leí sobre las colas en serie GCD que puede crear, ejecute sus 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:
Permite agregar dependencia y le permite eliminar la dependencia, por lo que para una transacción puede ejecutar secuencialmente usando dependencia y para otra transacción que se ejecuta simultáneamente, mientras que GCD no permite ejecutar de esta manera.
Es fácil cancelar una operación si está en la cola, puede detenerse si se está ejecutando.
Puede definir el número máximo de operaciones concurrentes.
Puede suspender la operación que están en la cola
Puede encontrar cuántas operaciones pendientes hay en la cola.
fuente
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 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. Debe subclasificar NSOperation, debe escribir su código correctamente para que la cancelación y la finalización correcta de una tarea funcionen correctamente. Entonces, para cosas simples, usa 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 con GCD, por lo que no hay una buena razón para usarlas).
fuente
Bueno, NSOperations es simplemente una API construida sobre Grand Central Dispatch. Entonces, cuando está usando NSOperations, todavía está usando Grand Central Dispatch. Es solo que NSOperations le brinda algunas características sofisticadas que podrían gustarle. Puede hacer que algunas operaciones dependan de otras operaciones, reordenar las colas después de sumar elementos, y otras cosas por el estilo. De hecho, ImageGrabber ya está utilizando NSOperations y colas de operaciones. ASIHTTPRequest los usa bajo el capó, y puede configurar la cola de operaciones que usa para diferentes comportamientos si lo desea. Entonces, ¿cuál deberías usar? Lo que tenga sentido para su aplicación. Para esta aplicación es bastante simple, por lo que solo utilizamos Grand Central Dispatch directamente, sin necesidad de las características sofisticadas de NSOperation. Pero si los necesita para su aplicación, ¡no dude en usarla!
fuente