El hilo principal "Bloquear" (dispatch_get_main_queue ()) y (o no) ejecuta currentRunLoop periódicamente, ¿cuál es la diferencia?

Tengo el siguiente código:

- (void)test_with_running_runLoop { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); NSTimeInterval checkEveryInterval = 0.05; NSLog(@"Is main queue? : %d", dispatch_get_current_queue() == dispatch_get_main_queue()); dispatch_async(dispatch_get_main_queue(), ^{ sleep(1); NSLog(@"I will reach here, because currentRunLoop is run"); dispatch_semaphore_signal(semaphore); }); while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:checkEveryInterval]]; NSLog(@"I will see this, after dispatch_semaphore_signal is called"); } - (void)test_without_running_runLoop { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); NSLog(@"Is main queue? : %d", dispatch_get_current_queue() == dispatch_get_main_queue()); dispatch_async(dispatch_get_main_queue(), ^{ sleep(1); NSLog(@"I will not reach here, because currentRunLoop is not run"); dispatch_semaphore_signal(semaphore); }); NSLog(@"I will just hang here..."); while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)); NSLog(@"I will see this, after dispatch_semaphore_signal is called"); } 

produciendo lo siguiente:

 Starting CurrentTests/test_with_running_runLoop 2012-11-29 08:14:29.781 Tests[31139:1a603] Is main queue? : 1 2012-11-29 08:14:30.784 Tests[31139:1a603] I will reach here, because currentRunLoop is run 2012-11-29 08:14:30.791 Tests[31139:1a603] I will see this, after dispatch_semaphore_signal is called OK (1.011s) Starting CurrentTests/test_without_running_runLoop 2012-11-29 08:14:30.792 Tests[31139:1a603] Is main queue? : 1 2012-11-29 08:14:30.797 Tests[31139:1a603] I will just hang here... 

Mis preguntas están relacionadas entre sí:

1) Si lo entiendo bien, la queue principal (dispatch_get_main_queue ()) es una queue de serie. Bloqueo la queue principal / hilo principal con dispatch_semaphore_wait, así que ¿por qué veo "Llegaré aquí porque se ejecuta currentRunLoop" en el primer caso de testing (estoy bien con el segundo caso, en mi opinión, lo hace, lo que debería)

2) Cómo una queue en serie , con la tarea de ejecución actual bloqueada, puede tener una próxima tarea (oh, este misterioso runLoop: beforeDate 🙂 enviado antes de que se desbloquee el actual?

Quiero escuchar una respuesta detallada y exhaustiva sobre esto, porque ¡muy, muchas cosas (aquí en torno a SO también) dependen de este problema!

ACTUALIZACIÓN: Además de la respuesta aceptada, este tema SO tiene una buena respuesta a esta pregunta: Patrón para la queue asíncrona de testings de unidad que llama a la queue principal al finalizar

Porque el runloop pnetworkingeterminado en el hilo principal tiene el comportamiento especial que, cuando se ejecuta, también procesa para la queue de envío principal. En este caso, no está bloqueando porque le está diciendo a dispatch_semaphore_wait que espere el time de espera de inmediato, lo que está haciendo (devuelve non-zero, que evalúa en if a true), por lo que ejecuta su loop while, donde maneja el actual ejecutar bucle y, por lo tanto, su bloque enqueuedo se ejecuta.

Pero mi respuesta es amplia porque no estoy seguro de qué parte te sorprende.