O thread principal do "bloco" (dispatch_get_main_queue ()) e (ou não) executa o currentRunLoop periodicamente - qual é a diferença?
Eu tenho o seguinte 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");
}
produzindo o seguinte:
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...
Minhas perguntas estão relacionadas entre si:
1) Se eu entendi direito, a fila principal (dispatch_get_main_queue ()) é uma fila serial. Bloquear o principal thread / thread principal com dispatch_semaphore_wait, então por que eu vejo o"Eu vou chegar aqui, porque o currentRunLoop é executado" no primeiro caso de teste (eu estou bem com o segundo caso - no meu entendimento, o que deveria)
2) Como umserial fila, tendo a tarefa de execução atual bloqueada, pode ter uma próxima tarefa (oh, este misterioso runLoop: beforeDate :) despachado antes do atual ser desbloqueado?
Eu quero escutardetalhado ecompreensivo responder sobre isso, porque muito, muito mais coisas (aqui em torno de SO também) dependem desta questão!
ATUALIZAR: Além da resposta aceita, este tópico de SO tem uma boa resposta para essa pergunta:Padrão para a fila assíncrona de teste de unidade que chama a fila principal na conclusão