这与我之前的问题有关,但不同的是,我想我会把它扔到一个新的问题中。我有一些代码在自定义队列上运行异步,然后在完成时在主线程上执行完成块。我想围绕这个方法编写单元测试。我的方法MyObject
看起来像这样。
+ (void)doSomethingAsyncThenRunCompletionBlockOnMainQueue:(void (^)())completionBlock {
dispatch_queue_t customQueue = dispatch_queue_create("com.myObject.myCustomQueue", 0);
dispatch_async(customQueue, ^(void) {
dispatch_queue_t currentQueue = dispatch_get_current_queue();
dispatch_queue_t mainQueue = dispatch_get_main_queue();
if (currentQueue == mainQueue) {
NSLog(@"already on main thread");
completionBlock();
} else {
dispatch_async(mainQueue, ^(void) {
NSLog(@"NOT already on main thread");
completionBlock();
});
}
});
}
为了额外的安全,我加入了主队列测试,但它总是命中dispatch_async
. 我的单元测试如下所示。
- (void)testDoSomething {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
void (^completionBlock)(void) = ^(void){
NSLog(@"Completion Block!");
dispatch_semaphore_signal(sema);
};
[MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:completionBlock];
// Wait for async code to finish
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
STFail(@"I know this will fail, thanks");
}
我创建了一个信号量,以阻止测试在异步代码完成之前完成。如果我不需要完成块在主线程上运行,这将非常有用。但是,正如我在上面链接的问题中指出的那样,测试在主线程上运行然后我将完成块排入主线程的事实意味着我将永远挂起。
从异步队列调用主队列是我经常看到的用于更新 UI 等的模式。有没有人有更好的模式来测试回调到主队列的异步代码?