Dre*_*its 41 objective-c grand-central-dispatch sentestingkit
我在使用内置的Xcode单元测试框架SenTestingKit测试一些宏的中央调度代码时遇到了一些麻烦.我成功地解决了我的问题.我有一个单元测试,它构建一个块并尝试在主线程上执行它.但是,该块永远不会被实际执行,因此测试会挂起,因为它是同步调度.
- (void)testSample {
dispatch_sync(dispatch_get_main_queue(), ^(void) {
NSLog(@"on main thread!");
});
STFail(@"FAIL!");
}
Run Code Online (Sandbox Code Playgroud)
什么是导致它挂起的测试环境?
BJ *_*mer 108
dispatch_sync在给定队列上运行一个块并等待它完成.在这种情况下,队列是主调度队列.主队列以FIFO(先进先出)顺序在主线程上运行其所有操作.这意味着无论何时调用dispatch_sync,您的新块都将放在该行的末尾,并且在队列中的其他所有内容完成之前不会运行.
这里的问题是,你刚刚入队的块是在结束等待上运行线的主线,而testSample方法是目前主要的线程上运行.在当前方法(本身)完成使用主线程之前,队列末尾的块无法访问主线程.但是,dispatch_sync意味着提交块对象以便在调度队列上执行,并等待该块完成.
在你的代码的问题是,不管你使用的dispatch_sync还是dispatch_async,STFail()总是会叫,会导致测试失败.
更重要的是,正如BJ Homer所解释的,如果你需要在主队列中同步运行某些东西,你必须确保你不在主队列中或者发生死锁.如果您在主队列中,则可以将块作为常规函数运行.
希望这可以帮助:
- (void)testSample {
__block BOOL didRunBlock = NO;
void (^yourBlock)(void) = ^(void) {
NSLog(@"on main queue!");
// Probably you want to do more checks here...
didRunBlock = YES;
};
// 2012/12/05 Note: dispatch_get_current_queue() function has been
// deprecated starting in iOS6 and OSX10.8. Docs clearly state they
// should be used only for debugging/testing. Luckily this is our case :)
dispatch_queue_t currentQueue = dispatch_get_current_queue();
dispatch_queue_t mainQueue = dispatch_get_main_queue();
if (currentQueue == mainQueue) {
blockInTheMainThread();
} else {
dispatch_sync(mainQueue, yourBlock);
}
STAssertEquals(YES, didRunBlock, @"FAIL!");
}
Run Code Online (Sandbox Code Playgroud)
如果你必须先等自己走出家门,你会走出家门吗?你猜对了!不!:]
基本上如果:
main_queue)syncie 以串行方式调用该方法并希望在 FooQueue 上执行。出于同样的原因,这种情况永远不会发生,因为您将永远无法走出家门!
它永远不会被调度,因为它正在等待自己离开队列!
| 归档时间: |
|
| 查看次数: |
19687 次 |
| 最近记录: |