我想包装一个如下所示的异步 API:
[someObject completeTaskWithCompletionHandler:^(NSString *result) {
}];
进入一个同步方法,我可以这样调用:
NSString *result = [someObject completeTaskSynchronously];
我该怎么做呢?我做了一些文档阅读和互联网搜索,并尝试使用“dispatchsemaphore”来尝试实现它,如下所示:
-(NSString *) completeTaskSynchronously {
__block NSString *returnResult;
self.semaphore = dispatch_semaphore_create(0);
[self completeTaskWithCompletionHandler:^(NSString *result) {
resultResult = result;
dispatch_semaphore_signal(self.semaphore);
}];
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
return resultResult;
}
但这似乎不起作用,它基本上只是停在dispatch_semaphore_wait。执行永远不会到达执行 _signal 的内部块。有人有关于如何执行此操作的代码示例吗?我怀疑该块必须位于主线程之外的不同线程上?另外,假设我无权访问异步方法背后的源代码。
dispatch_semaphore_wait
在您的示例中阻塞主队列。您可以将异步任务分派到不同的队列:
__block NSString *returnResult;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_async(queue,^{
result = [someObject completeTaskSynchronously];
});
或者使用其他系统,例如 NSRunLoop:
__block finished = NO;
[self completeTaskWithCompletionHandler:^(NSString *result) {
resultResult = result;
finished = YES;
}];
while (!finished) {
// wait 1 second for the task to finish (you are wasting time waiting here)
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)