Lo he estado usando DispatchQueue.main.async
durante mucho tiempo para realizar operaciones relacionadas con la interfaz de usuario.
Swift proporciona ambos DispatchQueue.main.async
y DispatchQueue.main.sync
, y ambos se realizan en la cola principal.
¿Alguien puede decirme la diferencia entre ellos? ¿Cuándo debo usar cada uno?
DispatchQueue.main.async {
self.imageView.image = imageView
self.lbltitle.text = ""
}
DispatchQueue.main.sync {
self.imageView.image = imageView
self.lbltitle.text = ""
}
fuente
DispatchQueue.main.sync
desde un hilo en segundo plano?async
allí. Quiero decir, dado que no hay nada más en el hilo después, no hace ninguna diferencia. Si lo fuera,DispatchQueue.main.sync {block1}; DispatchQueue.main.sync {block2};
entonces habría tenido sentido. Pero cuando no hay otro bloque, no puedo pensar en el beneficio de usarDispatchQueue.main.sync {Oneblock}
overDispatchQueue.main.async {Oneblock}
. Para ambos obtendrán la prioridad / inmediatez de mainQueue y nada los interrumpirá.¿Por qué la concurrencia?
Tan pronto como agrega tareas pesadas a su aplicación, como la carga de datos, ralentiza el trabajo de la interfaz de usuario o incluso lo congela. La concurrencia le permite realizar 2 o más tareas “simultáneamente”. La desventaja de este enfoque es que la seguridad de los hilos no siempre es tan fácil de controlar. Fe cuando diferentes tareas quieren 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 conocer.
Colas
Debe ser serial o concurrente . Así como global o privada al mismo tiempo.
Con las colas en serie, las tareas se terminarán una por una, mientras que con las colas simultáneas, 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 simultánea.
Puede crear sus propias colas privadas (tanto en serie como simultáneas ) o utilizar 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 estén relacionadas con el trabajo de la interfaz de usuario en la cola principal (por ejemplo, cargar datos de la red), sino realizarlas en las otras colas para mantener la interfaz de usuario descongelada y receptiva a las acciones del usuario. Si permitimos que se cambie la interfaz de usuario en las otras colas, los cambios se pueden realizar en un horario y velocidad diferentes e inesperados. Algunos elementos de la interfaz de usuario se pueden dibujar antes o después de que se necesiten. 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 algunas otras tareas en ellas.
Calidad de servicio / prioridad
Las colas también tienen diferentes qos (Calidad de servicio) que establecen la prioridad de ejecución de la tarea (de mayor a menor aquí):
.userInteractive - cola principal
.userInitiate - para las tareas iniciadas por el usuario en las que el usuario espera alguna respuesta
.utility - para las tareas que lleva algo de tiempo y no requiere 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
una cola .default que no transfiere la información de qos . Si no fuera posible detectar los qos la qos utilizará entre .userInitiate y .utility .
Las tareas se pueden realizar de forma sincrónica o asincrónica .
Sincrónico función 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.
Asincrónico función 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 termine la tarea. No bloquea la cola.
Problemas comunes.
Los errores más populares que cometen los programadores al proyectar las aplicaciones simultáneas son los siguientes:
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 a que se complete la tarea, pero la tarea nunca se terminará ya que ni siquiera podrá comenzar debido a que la cola es ya bloqueado. Se llama punto muerto .
¿Cuándo usar la sincronización? Cuando necesitamos esperar hasta que finalice la tarea. Fe cuando nos aseguramos de que alguna función / método no se llame doblemente. Tenemos sincronización y estamos tratando de 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 bloqueo de errores en el dispositivo IOS?
fuente
DispatchQueue.main.sync
desde un hilo en segundo plano?sync
oasync
métodos no tienen ningún efecto en la cola en la que se llaman.sync
bloqueará el hilo desde el que se llama y no la cola en la que se llama. Es la propiedad de laDispatchQueue
que decide si elDispatchQueue
esperará la ejecución de la tarea (cola en serie) o puede ejecutar la siguiente tarea antes de que finalice la tarea actual (cola simultánea).Entonces, incluso cuando
DispatchQueue.main.async
es una llamada asíncrona, una operación de trabajo pesado agregada puede congelar la interfaz de usuario ya que sus operaciones se ejecutan en serie en el hilo principal. Si se llama a este método desde el subproceso en segundo plano, el control volverá a ese subproceso instantáneamente incluso cuando la interfaz de usuario parezca estar congelada. Esto se debe a que laasync
llamada se realiza enDispatchQueue.main
fuente
GCD
le permite ejecutar una tareasynchronously
oasynchronously
[Acerca de] [Más]synchronous
La función (bloquear y esperar) devuelve un control cuando se completará la tareaasynchronous
La función (enviar y continuar) devuelve un control inmediatamente, enviando la tarea para que comience a una cola adecuada, pero sin esperar a que se complete.fuente