iphone - ¿Qué sucederá si tengo llamadas dispatch_async anidadas?
ios objective-c (1)
Puede ser una pregunta tonta, pero necesito preguntar y aclarar esto por mí mismo.
Para enviar un bloque a una cola para su ejecución, use las funciones dispatch_sync y dispatch_async . Ambos toman una cola y un bloque como parámetros. dispatch_async regresa de inmediato, ejecutando el bloque de forma asincrónica, mientras que dispatch_sync bloquea la ejecución hasta que el bloque proporcionado retorna. Aquí hay algunas situaciones:
Situación 1
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_async(queue, ^{
NSLog(@"this is statement1");
});
});
Situacion 2
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_sync(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_sync(queue, ^{
NSLog(@"this is statement1");
});
});
Situacion 3
{
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_sync(queue, ^{
NSLog(@"this is statement1");
});
});
Situación 4
{
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_sync(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_async(queue, ^{
NSLog(@"this is statement1");
});
});
}
Y goDoSomethingLongAndInvolved es
-(void)goDoSomethingLongAndInvolved {
NSLog(@"goDoSomethingLongAndInvolved");
}
Intenté ejecutarlos en Xcode pero no puedo ver la diferencia.
Así que mis preguntas son:
- ¿Cuál es la principal diferencia entre estas situaciones?
- ¿Qué pasa si reemplazo la
queuecondispatch_get_main_queue()?
La instrucción dispatch_sync espera hasta que el bloque que cubre se ejecute por completo. dispatch_async regresa inmediatamente y pasa a la siguiente línea de código, por lo que todo lo que está sucediendo sucede en paralelo.
Si la queue era una cola en serie creada por usted mismo, entonces:
Situación 1 - El bloque raíz regresa inmediatamente. En el interior espera por [self go ....], y luego va a dispatch_async, que también regresa de inmediato.
Situación 2 - Si la queue fuera una cola en serie, entonces habría un bloqueo muerto ya que esperará a que termine de ejecutarse. Como se trata de uno asíncrono, ese bloque se ejecutará en paralelo. (Gracias, @Ken Thomases)
Situación 3 - No hay necesidad en dispatch_sync aquí. Causa el punto muerto.
Situación 4 - Espera a [auto ...], luego regresa inmediatamente.
Si reemplaza la queue con la queue principal, recuerde no dispatch_sync en la cola principal, ya que causará un interbloqueo (no se enviará desde el hilo principal, gracias a @Ken Thomases).
Para entenderlo mejor, reemplaza tu función con:
-(void)goDoSomethingLongAndInvolved:(NSString *)message {
for(int i = 0; i < 50; ++i) {
NSLog(@"%@ -> %d", message, i);
}
}
Verás claramente lo que está sucediendo cada vez, ya sea que espere o no. Buena suerte.