【问题标题】:Make an AFNetworking operation complete before next code line after [operation start] and how to handle nested operations在[操作开始]之后的下一个代码行之前完成AFNetworking操作以及如何处理嵌套操作
【发布时间】:2013-06-09 20:38:16
【问题描述】:

我在 AFNetworking 中遇到了完成块的问题,我的应用程序需要获取有关汽车的 json 数据并使用此 json 文件中的 id 来请求另一个 api 来检索图像,然后才能在 uitableview 中显示所有汽车。但是 uitableview 重新加载总是在检索信息之前调用,因此它显示空表。

我有一个 Model.m typedef void (^CompletionBlock)(NSArray *results);

-(void)getPhotosWithCompletionBlock: (CompletionBlock)completionBlock failureBlock: (FailureBlock)failureBlock{
    NSURLRequest *request = [NSURLRequest alloc] initWithURL:[NSURL alloc] initWithString:
                            [NSString stringWithFormat:@"api.getPhoto"]]];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        completionBlock(JSON);
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        failureBlock(JSON);
    }];
    [operation start];
}

ModelViewController.m

- (void)getAllModels{
   NSURLRequest *request = ...;
   AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
     for(NSDictionary *model in JSON){
        Model *model = [Model alloc] initWithId:...;
        [model getPhotosWithCompletionBlock: ^(NSArray *results){
            model.photos = results;
         }failureBlock:^(NSError *error) {
                NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
            }];
      }
      [_tableView reloadData];
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
}];

[operation start];

但是[_tableView reload]总是在getPhotos方法的completionBlock完成之前调用,所以tableView是空的,那么如何在调用reload tableView方法之前使完成块完成呢?我可以将 reload 方法放在完成块中,但它会强制 tableView 重新加载多次使应用程序非常无响应,我还有 1 种方法来检索模型信息,所以我不能将 reload 方法放在每个完成块中。 P/S:对我的情况有什么想法不使用嵌套的afnetworking操作吗?

【问题讨论】:

    标签: objective-c-blocks afnetworking


    【解决方案1】:

    这不是与 AFNetworking 相关的问题,而是一般的Objective-Casynchronous问题。

    您可以尝试在加载了一个模型的图像时重新加载表格视图:

    - (void)getAllModels{
       NSURLRequest *request = ...;
       AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
         for(NSDictionary *model in JSON){
            Model *model = [Model alloc] initWithId:...;
            [model getPhotosWithCompletionBlock: ^(NSArray *results){
                dispatch_async(dispatch_get_main_queue(), ^{
                    model.photos = results; 
                    [self.tableView reloadData];
                });
             }failureBlock:^(NSError *error) {
                    NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
                }];
          }
        } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];
    

    发生错误时,您可能需要修复一些极端情况。

    如果存在性能问题,您需要检查它们发生的位置。一个常见的嫌疑人是在主线程上创建 UIImages。您可以将它们安排到另一个嵌入式异步任务,其完成块然后强制更新表视图,或在您的 getPhotosWithCompletionBock 方法中执行此操作。

    您也可以考虑更明确地说明您需要更新哪个单元格,而不是简单地发送reloadData:,这也会重新加载已经是最新的图像。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 2017-02-15
      • 1970-01-01
      相关资源
      最近更新 更多