【发布时间】:2012-11-29 06:34:28
【问题描述】:
我有以下代码:
- (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");
}
产生以下内容:
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...
我的问题彼此相关:
如果我理解正确的话,主队列 (dispatch_get_main_queue()) 是一个串行队列。我用dispatch_semaphore_wait阻塞了主队列/主线程,那么为什么我在第一个测试用例中看到“我会到达这里,因为currentRunLoop正在运行”(我对第二种情况没问题-以我的理解,它确实,它应该做什么)?
串行队列如何在当前执行任务被阻塞的情况下,在当前任务解锁之前调度下一个任务(哦,这个神秘的 runLoop:beforeDate:)?
我想听听详细和全面对此的回答,因为非常非常多的事情(这里也是如此)取决于这个问题!
更新:除了公认的答案,这个 SO 主题对这个问题有很好的答案:Pattern for unit testing async queue that calls main queue on completion
【问题讨论】:
标签: objective-c ios queue semaphore nsrunloop