https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2

Esta es la continuación de la concurrencia en la serie swift. Consulte la parte 1 y la parte 2 para comprender los conceptos básicos

En esta parte cubriremos los siguientes temas

  1. Qué son las operaciones y sus estados de vida
  2. Crear bloques, NSInvocationOperation y Operaciones personalizadas para ejecutar tareas asincrónicas
  3. Cómo cancelar operaciones
  4. Qué son colas de operaciones
  5. Cómo agregar Operaciones En Colas de Operaciones
  6. Cómo crear dependencias entre Operaciones
  7. Beneficios de las Colas de Operaciones Sobre GCD
  8. Implementación de Grupos de Despacho Mediante Colas de Operaciones

Las operaciones son un forma orientada a objetos de encapsular el trabajo que desea realizar de forma asíncrona. Las operaciones están diseñadas para usarse junto con una cola de operaciones o por sí mismas

Un objeto de operación es una instancia de la clase Operation or NSOperation (en el framework Foundation) que se utiliza para encapsular el trabajo que desea que realice la aplicación.

La clase de operación en sí es una clase base abstracta que debe ser subclase para hacer cualquier trabajo útil. A pesar de ser abstracta, esta clase proporciona una cantidad significativa de infraestructura para minimizar la cantidad de trabajo que tiene que hacer en sus propias subclases. Además, el framework Foundation proporciona dos subclases concretas que puede usar tal cual con su código existente.

Estado de operaciones

Una operación tiene una máquina de estados que representa su ciclo de vida. Hay varios estados posibles que ocurren en varias partes de este ciclo de vida:

  • Cuando haya pasado instantiated, pasará al estado isReady.
  • Cuando invocamos el método start, pasará al estado isExecuting.
  • Cuando la tarea finished, se mueve a isFinished
  • Cuando la tarea está en progreso y llamas a cancel, luego pasará al estado isCancelled antes de pasar al estado isFinished

Hay principalmente tres formas de crear operaciones

)

Una clase que se usa tal cual para ejecutar uno o más objetos de bloque simultáneamente. Debido a que puede ejecutar más de un bloque, un objeto de operación de bloque opera utilizando un grupo semántico; solo cuando todos los bloques asociados han terminado de ejecutarse, la operación en sí se considera terminada.. En la operación de bloques, puede aprovechar las dependencias de operación, KVO, notificaciones y cancelaciones .

Como se muestra en la Figura 1, ejecutamos este código async, lo que significa que volverá inmediatamente, pero la mala noticia es que bloqueará el hilo principal, ya que operation.start() fue llamado en el hilo principal

Los objetos de operación se ejecutan de manera sincrónica de forma predeterminada, es decir, realizan su tarea en el hilo que llama a su método start.

Figura 1

¿Qué diablos es la manera sincrónica y ejecutar uno o más bloques de los objetos al mismo tiempo.

Como se muestra en la Figura 1.0.1, como puede ver, las tareas / bloques agregados a la operación de bloque en sí se ejecutan simultáneamente, pero la ejecución de bloque de manera sincrónica significa que bloqueó el subproceso en el que se llama a start en nuestro caso, es el subproceso principal

Figura 1.0.1

Como se muestra en la figura Figura 1.0.2, ya que llamamos al método de inicio en otro subproceso, bloqueará ese subproceso

Gráfico 1.0.2

Como se muestra en la Figura Figura 1.0.3, también podemos agregar un bloque de finalización que llamará cuando se ejecuten todos los bloques simultáneos

Gráfico 1.0.3

Ejecute la operación de bloques simultáneamente

Como se muestra en la Figura 1.1 puesto que llamamos al método start() en un hilo de fondo, realizará su tarea en el hilo. Hay una forma genial de hacer esto usando la cola de operaciones y veremos esto más adelante.

Figura 1.1

NSInvocationOperation (Clase Concreta)

Una clase que se utiliza como-es crear una operación objeto basado en un objeto y selector de su aplicación.

En objective C podemos crear NSInvocationOperation mientras no esté disponible en Swift.

https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW6

3. Operaciones personalizadas

La subclase Operation le brinda un control completo sobre la implementación de sus propias operaciones, incluida la capacidad de alterar la forma predeterminada en que se ejecuta su operación e informa de su estado.

Como se muestra en la Figura 2, creamos operaciones personalizadas por subclase desde Operation clase base y reemplazamos su método main. Cuando subclases, pones tu tarea en el método main. Implementamos una operación personalizada no concurrente y en este caso bloqueamos el hilo principal

Gráfico 2

Si planea ejecutar operaciones manualmente y aún desea que se ejecuten de forma asincrónica, debe tomar las acciones adecuadas para asegurarse de que lo hagan. Para ello, defina su objeto de operación como una operación concurrente.

Como se muestra en la Figura 3, realizamos los siguientes pasos para realizar tareas simultáneamente

  1. Subclase creada MyConcurrentQueue . Error tipográfico: El nombre debe ser MyConcurrentOperations
  2. Llamar a start() el método llamará a main() el método en el hilo de fondo
  3. En el método principal definimos nuestra tarea y una cosa a tener en cuenta también atendemos el caso de cancelación
  4. Al llamar a cancel en la operación personalizada, la transición al estado isCancelled y romper el bucle y, como se muestra en la Figura 3, imprimirá solo 39487 elementos

Gráfico 3

Colas de operaciones

  1. Las colas de operaciones son la abstracción de alto nivel de Cocoa en GCD
  2. Utilizando Colas de operaciones verá el poder real de las operaciones , en lugar de iniciar la operación usted mismo , se lo da a la cola de operaciones y luego se encarga de la programación y ejecución.
  3. Las colas de operación son una forma orientada a objetos de encapsular el trabajo que desea realizar de forma asincrónica.
  4. Agrega operations (tareas / trabajo) en operation queue y discutimos cómo podemos crear operaciones utilizando dos métodos.

Agregar operaciones

Como se muestra en la Figura 4, creamos dos operaciones (utilizando Bloques) y las agregamos a la cola de operaciones. La cola de operaciones inició ambas operaciones en algún subproceso en segundo plano y las ejecutó. No es necesario llamar al método start() en el hilo personalizado thread. Cuando agregamos operación a la cola de operaciones, se ejecuta tan pronto como está lista

Gráfico 4

Como se muestra en la Figura 5, acabamos de ejecutar la tarea en serie o puede decir que implementamos la cola en serie usando Colas de operación, consulte mi parte 1 si no sabe qué es la cola en serie configurando maxConcurrentOperationCount = 1

maxConcurrentOperationCount →El número máximo de operaciones en cola que se pueden ejecutar al mismo tiempo. El valor predeterminado es -1, lo que significa que deje que el sistema decida

Gráfico 5

Al establecer maxConcurrentOperationCount = 2 creamos una cola concurrente y ahora las tareas se ejecutan simultáneamente como se muestra en la Figura 6

Gráfico 6

Dependencias de operaciones

Como se muestra en la Figura 7, nuevamente creamos una cola serie agregando dependencias entre dos tareas. Hemos creado dos operaciones de bloque y estamos diciendo que no inicie la tarea 1 hasta que la tarea 2 haya terminado llamando blockOperations1.addDependency(blockOperations2)

Gráfico 7

Implementación de grupo de despacho Usando Cola de operaciones

En la parte 2 utilizamos la función grupo de despacho de GCD para bloquear un subproceso hasta que una o más tareas terminen de ejecutarse. Como se muestra en la Figura 8, implementamos el mismo comportamiento utilizando Colas de operaciones mediante dependencias. Esto es muy útil si no puede avanzar hasta que se completen todas las tareas especificadas.

Como se muestra en la Figura 8 tenemos tres tareas, y queríamos que se ejecutan simultáneamente y cuando todas las tareas de acabado tenemos que llamar a algún método para indicar que todas las tareas se ha terminado y lo que hicimos

  1. Crea una operación de cola
  2. Creado tres bloque de operaciones que va a realizar tareas de
  3. Crea un bloque de finalización de la operación (blockOperations4) que se disparará cuando todos los tres tareas terminado
  4. Hecho blockOperations4 dependiente blockOperations1, blockOperations2 y blockOperations3 que significa blockOperations4 se ejecutará cuando todos los tres tareas terminado
  5. waitUntilFinished → Bloquea la ejecución del subproceso actual hasta que el objeto de operación finalice su tarea ya que no queremos bloquear el subproceso actual que es principal, lo asignamos con false
  6. Ejecute este código y «Toda la operación se ha completado» se imprimirá cuando finalice task1, task2 y task3

Gráfico 8

Como se muestra en la Figura 9, simplemente bloqueamos el hilo principal configurando waitUntilFinished = true. Para que la pregunta sea cuándo es útil y obtendrá la respuesta en la siguiente sección

Gráfico 9

Como se muestra en la Figura 10, implementamos un comportamiento de grupo de despacho usando cola de operaciones sin usar dependencias .Lo que hicimos, usamos la característica waitUntilFinished apropiadamente. Si está en el hilo de fondo, puede bloquear este hilo para lograr este comportamiento. Cambié intencionalmente a subproceso en segundo plano utilizando el método DispatchQueue.global().async, consulte la parte 1 para comprender este código

Le dijimos a la cola de operaciones que ejecutara la tarea 1, la tarea 2 y la tarea 3 en la cola de operaciones y bloqueara el subproceso actual hasta que estas tareas simultáneas terminaran su ejecución

Gráfico 10

Beneficios de las colas de operación sobre GCD

  1. La API de operación proporciona soporte para dependencias. Puede crear dependencias complejas entre tareas muy fácilmente, aunque en GCD puede lograrlo, pero tiene que hacer mucho trabajo.
  2. Las clases NSOperation y NSOperationQueue tienen una serie de propiedades que se pueden observar, utilizando KVO (Key Value Observing). Este es otro beneficio importante si desea monitorear el estado de una operación o cola de operaciones.
  3. Las operaciones se pueden pausar, reanudar y cancelar. Una vez que envía una tarea utilizando Grand Central Dispatch, ya no tiene control ni información sobre la ejecución de esa tarea. La API de NSOperation es más flexible en ese sentido, dando al desarrollador control sobre el ciclo de vida de la operación
  4. La NSOperationQueue también agrega una serie de beneficios a la mezcla. Por ejemplo, puede especificar el número máximo de operaciones en cola que se pueden ejecutar simultáneamente. Esto facilita el control de cuántas operaciones se ejecutan al mismo tiempo o la creación de una cola de operaciones en serie.

Próximo

En la siguiente parte, veremos el caso de uso real de crear operaciones personalizadas

Enlaces útiles

· https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW1

Deja una respuesta

Tu dirección de correo electrónico no será publicada.