iphone ios objective-c objective-c-blocks grand-central-dispatch

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:

  1. ¿Cuál es la principal diferencia entre estas situaciones?
  2. ¿Qué pasa si reemplazo la queue con dispatch_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.