我需要向同一个 API 发出 12 个请求(数据更改)。每次发出请求时,我都想将检索到的数据添加到我的数组中。我知道如何做到这一点的方式被称为回调 hell 。看起来像这样
NSMutableArray *dataArray = [[NSMutableArray alloc] init]
[self getRequestonPage:1 completion:^(BOOL succeeded, int data) {
[dataArray addObject:data];
[self getRequestonPage:2 completion:^(BOOL succeeded, int data) {
[dataArray addObject:data];
[self getRequestonPage:3 completion:^(BOOL succeeded, int data) {
[dataArray addObject:data];
}];
}];
}];
......等等,等等,有 12 个嵌套的异步完成处理程序。
完成所有请求后,我想用数组中的数据更新我的 UI。必须有一种更漂亮的方法来做到这一点。
有什么想法吗?
最佳答案
以下是执行任意数量的异步请求并知道它们何时完成的方法:
(1) 用参数化请求来表示请求。在您的情况下,请求由页码表示。
NSArray *pages = @[ @1, @2, @3 /* ... */ ];
(2) 用将请求参数与异步操作的结果相关联的字典表示结果:
NSMutableDictionary *results = [@{} mutableCopy];
(3) 执行列表的递归算法是这样的:如果列表为空,我们就完成了,否则,执行列表中的第一件事,然后执行列表的其余部分。在代码中,您将调用:
[self getPages:pages filling:results completion:^(BOOL success) {
// here, we can update our UI
// collecting the results in a dictionary allows us to know
// which result goes with which request
}];
- (void)getPages:(NSArray *)pages filling:(NSMutableDictonary *)results completion:(void (^)(BOOL))completion {
NSInteger count = pages.count;
// degenerate case is an empty array which means we're done
if (!count) return completion(YES);
// otherwise, do the first operation on the to do list, then do the remainder
NSNumber *page = pages[0];
NSArray *remainder = [pages subarrayWithRange:NSMakeRange(0, count-1)];
[self getRequest:[page intValue] completion:^(BOOL *success, int data) {
if (success) {
results[page] = @(data);
[self getPages:remainder filling:results completion:completion];
} else {
completion(NO);
}
}];
}
注意,为了使用 NS 集合,我们将页码 int
和返回的 int
“包装”为 NSNumber
。但结果将如下所示:
@{ @1 : @42, @2 : @154, etc...
@42 和 @154 是 getRequest 完成 block 返回的 NSNumber 包装整数。
关于ios - 在多个异步完成处理程序完成后更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32086624/