我正在编写一个网络 API。由于对 NSURLSession
的底层调用始终是异步的,因此我默认提供了一个异步 API:
- (void) callBackendServerWithCompletion: (dispatch_block_t) completion;
提供此 API 的同步版本也非常方便,例如简化在 Xcode Playground 中测试代码。同步调用是按照异步调用来写的:
- (void) callBackendSynchronously
{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self callBackendServerWithCompletion:^{
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
这很好用。
现在我想添加一个额外的便利功能,一个默认调度队列来调用完成 block 。此回调队列默认为 UI 队列,因此此 API 的使用者不必一直 dispatch_async(dispatch_get_main_queue(), ^{…})
:
// This:
[webservice callBackendServerWithCompletion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self updateUI];
});
}];
// Would be replaced with this:
[webservice callBackendServerWithCompletion:^{
// Guaranteed to run on the main queue
[self updateUI];
}];
这很容易做到,但是现在我在主队列上调用同步方法时出现了死锁:
-callBackendSynchronously
调用 -callBackendServerWithCompletion
并等待信号量。提供所有三个功能的简单方法是什么,即。同步和异步 API 方法以及默认回调队列?
添加一个私有(private)的、重载版本的 callBackendServerWithCompletion
接受调度队列。在 callBackendSynchronously
中,使用自定义后台队列调用这个新的重载方法。
最后,在您原来的callBackendServerWithCompletion
方法中调用重载版本,将默认队列作为参数传递。
关于ios - 提供带有目标回调队列的异步和同步 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43180988/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |