我在使用内置的Xcode单元测试框架SenTestingKit测试一些宏的中央调度代码时遇到了一些麻烦 . 我成功地解决了我的问题 . 我有一个单元测试,它构建一个块并尝试在主线程上执行它 . 但是,该块永远不会被实际执行,因此测试会挂起,因为它是同步调度 .
- (void)testSample {
dispatch_sync(dispatch_get_main_queue(), ^(void) {
NSLog(@"on main thread!");
});
STFail(@"FAIL!");
}
什么是导致它挂起的测试环境?
5 回答
dispatch_sync
在给定队列上运行一个块并等待它完成 . 在这种情况下,队列是主调度队列 . 主队列以FIFO(先进先出)顺序在主线程上运行其所有操作 . 这意味着无论何时调用dispatch_sync
,您的新块都将放在该行的末尾,并且在队列中的其他所有内容完成之前不会运行 .这里的问题是你刚入列的块是在等待在主线程上运行的行的末尾 - 而
testSample
方法 is 当前在主线程上运行 . 在当前方法(本身)完成使用主线程之前,队列末尾的块无法访问主线程 . 但是dispatch_sync
表示提交块对象以便在调度队列上执行,并等待该块完成 .您的代码中的问题是,无论您使用
dispatch_sync
还是dispatch_async
,都将始终调用STFail()
,从而导致测试失败 .更重要的是,正如BJ Homer所解释的,如果你需要在主队列中同步运行某些东西,你必须确保你不在主队列中或者发生死锁 . 如果您在主队列中,则可以将块作为常规函数运行 .
希望这可以帮助:
如果您在主队列中并同步等待主队列可用,您确实会等待很长时间 . 您应该测试以确保您不在主线程上 .
跟进,从那以后
现已弃用,您可以使用
看你是否在主线程上 .
因此,使用上面的其他答案,您可以:
如果你必须先让自己先出屋,你会不会离开家?你猜对了!没有! :]
基本上如果:
你是 on FooQueue . (不一定是
main_queue
)您使用
sync
调用方法,即以串行方式调用,并希望 execute on FooQueue .永远不会出于同样的原因,你永远不会离开家!
它不会被派遣,因为它必须等待自己下车!