Haupt-Thread (dispatch_get_main_queue ()) blockieren und currentRunLoop regelmäßig ausführen (oder nicht) - was ist der Unterschied?
Ich habe folgenden Code:
- (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");
}
Herstellung der folgenden:
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...
Meine Fragen beziehen sich aufeinander:
1) Wenn ich es richtig verstehe, ist die Hauptwarteschlange (dispatch_get_main_queue ()) eine serielle Warteschlange. Ich blockiere die Hauptwarteschlange / den Hauptthread mit dispatch_semaphore_wait, also warum sehe ich das?"Ich werde hier erreichen, weil currentRunLoop ausgeführt wird" im ersten Testfall (ich bin mit dem zweiten Fall einverstanden - nach meinem Verständnis tut es, was es sollte)?
2) Wie aseriell Die Warteschlange, in der die aktuelle ausgeführte Aufgabe blockiert ist, kann eine nächste Aufgabe haben (oh, diese mysteriöse runLoop: beforeDate :), die ausgelöst wurde, bevor die aktuelle entsperrt wurde?
Ich möchte hörendetailliert undumfassend antworte darauf, denn sehr, sehr viele Dinge (hier auch auf SO) hängen von diesem Thema ab!
AKTUALISIEREN: Abgesehen von der akzeptierten Antwort hat dieses SO-Thema eine gute Antwort auf diese Frage:Muster für die asynchrone Warteschlange zum Testen von Einheiten, die nach Abschluss die Hauptwarteschlange aufruft