thread grand gcd dispatchqueue dispatch_async central async ios swift multithreading swift3 concurrency

ios - grand - Diferencia entre DispatchQueue.main.async y DispatchQueue.main.sync



multithreading swift 4 (2)

Cuando usa async , permite que la cola de llamada avance sin esperar hasta que se ejecute el bloque despachado. Por el contrario, la sync hará que la cola de llamadas se detenga y espere hasta que se complete el trabajo que ha enviado en el bloque. Por lo tanto, la sync está sujeta a puntos muertos. Intente ejecutar DispatchQueue.main.sync desde la cola principal y la aplicación se congelará porque la cola de llamada esperará hasta que termine el bloque enviado pero ni siquiera podrá comenzar (porque la cola se detiene y espera)

¿Cuándo usar la sync ? Cuando necesite esperar a que se haga algo en una COLA DIFERENTE y solo entonces continuar trabajando en su cola actual

Ejemplo de uso de sincronización:

En una cola en serie, puede usar la sync como mutex para asegurarse de que solo un subproceso pueda ejecutar el código protegido al mismo tiempo.

Esta pregunta ya tiene una respuesta aquí:

He estado usando DispatchQueue.main.async desde hace mucho tiempo para realizar algunas operaciones relacionadas con la interfaz de usuario. Pero Swift proporciona DispatchQueue.main.async y DispatchQueue.main.sync y ambos se realizan en la cola principal. Entonces, ¿alguien puede decirme la diferencia entre ellos? ¿Y cuándo debo usarlos? Gracias de antemano.

DispatchQueue.main.async { self.imageView.image = imageView self.lbltitle.text = "" } DispatchQueue.main.sync { self.imageView.image = imageView self.lbltitle.text = "" }


¿Por qué concurrencia? Tan pronto como agrega tareas pesadas a su aplicación, como la carga de datos, ralentiza su trabajo de interfaz de usuario o incluso la congela. La concurrencia le permite realizar 2 o más tareas "simultáneamente". La desventaja de este enfoque es que la seguridad del hilo no siempre es tan fácil de controlar. Por ejemplo, cuando diferentes tareas desean acceder a los mismos recursos, como intentar cambiar la misma variable en diferentes subprocesos o acceder a los recursos ya bloqueados por los diferentes subprocesos.

Hay algunas abstracciones que debemos tener en cuenta.

  • Colas
  • Rendimiento de tarea sincrónica / asincrónica.
  • Prioridades
  • Problemas comunes

Colas

Debe ser serial o concurrente . Así como global o privado al mismo tiempo.

Con las colas en serie, las tareas se terminarán una por una, mientras que con las colas concurrentes, las tareas se realizarán simultáneamente y se terminarán en horarios inesperados. El mismo grupo de tareas llevará más tiempo en una cola en serie en comparación con una cola concurrente.

Puede crear sus propias colas privadas (tanto seriales como concurrentes ) o usar colas globales (del sistema) ya disponibles. La cola principal es la única cola en serie de todas las colas globales .

Se recomienda encarecidamente no realizar tareas pesadas que no se refieren al trabajo de la interfaz de usuario en la cola principal (por ejemplo, cargar datos desde la red), sino hacerlas en las otras colas para mantener la interfaz de usuario sin congelar y responder a las acciones del usuario. Si permitimos que se cambie la IU en las otras colas, los cambios se pueden realizar en un horario y velocidad diferentes e inesperados. Algunos elementos de la IU se pueden dibujar antes o después de que sean necesarios. Puede bloquear la interfaz de usuario. También debemos tener en cuenta que, dado que las colas globales son colas del sistema, el sistema puede ejecutar otras tareas en ellas.


Calidad de servicio / prioridad .

Las colas también tienen diferentes qos (calidad de servicio) que establece la prioridad de ejecución de la tarea (de mayor a menor aquí):
.userInteractive - cola principal
.userInitiated : para las tareas iniciadas por el usuario en las que el usuario espera alguna respuesta
.utilidad : para las tareas que requieren algo de tiempo y no requieren una respuesta inmediata, por ejemplo, trabajar con datos
.background : para las tareas que no están relacionadas con la parte visual y que no son estrictas para el tiempo de finalización).

También hay

. cola predeterminada que no transfiere la información del qos . Si no fuera posible detectar el qos, el qos se usará entre .userInitiated y .utility .

Las tareas se pueden realizar de forma sincrónica o asincrónica .

  • La función síncrona devuelve el control a la cola actual solo después de que finaliza la tarea. Bloquea la cola y espera hasta que finalice la tarea.

  • La función asincrónica devuelve el control a la cola actual justo después de que se haya enviado la tarea para que se realice en la cola diferente. No espera hasta que finalice la tarea. No bloquea la cola.

Problemas comunes

Los errores más populares que cometen los programadores al proyectar las aplicaciones concurrentes son los siguientes:

  • Condición de carrera : causada cuando el trabajo de la aplicación depende del orden de ejecución de las partes del código.
  • Inversión de prioridad : cuando las tareas de mayor prioridad esperan a que finalicen las tareas de menor prioridad debido al bloqueo de algunos recursos
  • Punto muerto : cuando algunas colas tienen una espera infinita para las fuentes (variables, datos, etc.) ya bloqueadas por algunas de estas colas.

NUNCA llame a la función de sincronización en la cola principal .
Si llama a la función de sincronización en la cola principal, bloqueará la cola y la cola estará esperando que se complete la tarea, pero la tarea nunca se completará, ya que ni siquiera podrá iniciarse debido a que la cola está ya bloqueado Se llama punto muerto .

¿Cuándo usar la sincronización? Cuando necesitamos esperar hasta que termine la tarea. Fe cuando nos estamos asegurando de que alguna función / método no se llame doblemente. Fe tenemos sincronización e intentamos evitar que se llame dos veces hasta que esté completamente terminado. Aquí hay un código para esta preocupación:
¿Cómo averiguar qué causó el informe de error en el dispositivo IOS?