将同步转换为异步 Objective-C



我正在一个新的代码库中工作,我没有多少人理解它,所以我希望我能得到一些帮助。我正在更新一个接口,一些同步方法现在是异步的,这使得很难适应当前的架构来解析数据。

目前我们有一个存储这些同步方法的函数映射,然后当我们想要数据时,我们执行"调用",执行块/方法并返回值。

下面的一些代码显示了它目前的情况。

fnMap[@“vid”] = [[Callback alloc] initWithBlock:^id(id param) {
return @([services getVisitorID]);
}];
… later, to resolve the data 
id fnMapVal = [fnMap[key] call:nil];

以下是回调和回调块的定义方式。

typedef id (^CallbackBlock)(id);
@interface Callback : NSObject
@property(copy, nonatomic, readonly) CallbackBlock block;
- (instancetype)initWithBlock:(CallbackBlock)block

- (id)call:(id)param
{
return self.block(param);
}

现在服务需要调用异步方法来获取 ID,所以我不得不将其更改为:

- (void)getVisitorID: (nullable void (^) (NSString* __nullable visitorIdentifier)) callback
{
[SDK getUserIdentifier:^(NSString * _Nullable userIdentifier) {
callback(userIdentifier);
}];
}

所以电话是:

[services getVisitorID:^(NSString * _Nullable visitorIdentifier) {
}];

我一直无法找到将其融入当前架构的方法。我探索的一些选项是使用运行循环来等待异步方法完成并保持我的接口同步,但这听起来是个坏主意。我正在寻求一些关于如何适应它的建议,因为我以前从未见过这样的东西。

您需要使用 dispatch_queues 或 NSOperationQueue 在主线程上运行代码。调度队列的级别非常低,适合启动异步任务:

// we're going to run the getVisitorID method on a background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[services getVisitorID:^(NSString * _Nullable visitorIdentifier) {
dispatch_async(dispatch_get_main_queue(), ^(void){
// update the user interface on the main queue
});
}];
});

我更喜欢使用 NSOperationQueue,因为 API 更干净,它们允许您执行更高级的操作,例如使异步任务可取消:

// create a background queue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
[services getVisitorID:^(NSString * _Nullable visitorIdentifier) {
// get the main queue and add your UI update code to it
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// update the UI from here
}];
}];
}];

队列比弄乱运行循环更容易管理。有关更多信息,请参阅此处:https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

你需要的是未来/承诺的概念。请不要重新发明轮子,您将不得不跨越马拉松距离,试图实现请求价值和异步消费价值的相同功能。 作为收藏夹之一,请考虑PromiseKit。但是,不要害羞地探索替代方案

你很快就会发现它非常令人愉快地构建异步任务链,将它们的结果映射到不同的值,将未来组合在一起以获得多个解析值的元组,一旦所有值都可用 - 所有这些都以简洁、精心设计的形式进行,在数百万个应用程序中进行了实时测试。

最新更新