ios - 在多个异步完成处理程序完成后更新 UI

标签 ios objective-c xcode

我需要向同一个 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/

相关文章:

ios - 无法使用 AFNetworking 2.0 使用 GET 方法获取响应

ios - 如何通过Core Data验证将有意义的错误消息返回给 View Controller ?

ios - 音乐播放器不播放所选项目

swift - XCFramework 问题,标识符为 "ios-armv7_arm64"的库已经存在

ios - -[不是类型 _cfTypeID] : message sent to deallocated instance

ios - SKAction scaleXTo :-1

objective-c - 从核心数据和多线程中获取数据时的效率

ios - 我如何告诉地址簿选择器要填写哪些字段?

swift - Xcode 10 Struct Initializer autoComplete 不显示

ios - 如何更改 UIImagePicker 中的导航栏标题?