在 iOS 中链接异步操作

Chaining asynchronous operations in iOS

我正在尝试修复从 Google 的 URL 下载记录的应用程序,其中包含 79 条记录。我的应用加载前 70 个,然后意外停止。

我继承了具有 loadLatLong 方法的代码,它通过 AFHTTPRequestOperationManager 向 URL 发出 GET 请求,然后在 AFHTTPRequestOperationManager 中等待回调=15=] 块处理程序。

我觉得不对的部分是:当success:回调到达时,块再次调用loadLatLong方法,这会增加计数器,并发送另一个具有相同块的块.这一直持续到所有零件都加载完毕。不幸的是,这个过程提前停止了,这让我觉得这种链接请求的方式有问题。

这种处理来自 URL 的一系列 GET 调用的方法是否合适,我的错误在别处?是否有更好的链接异步调用的方法?

代码如下:

- (void)loadLatLong {
    indx++;
    if (indx == [datalist count]) {
        [self showMarker];
        [self.progressbar setProgress:1.0 animated:YES];
        return;
    }
    PointClass *pt = datalist[indx];
    NSString *stPt = [pt.Location stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSString *str = [stPt stringByReplacingOccurrencesOfString:@" " withString:@"+"];
    NSString *url = [NSString stringWithFormat:@"https://maps.google.com/maps/api/geocode/json?address=%@&sensor=false&key=<API KEY>", str];

    NSURL *urlString = [NSURL URLWithString:url];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
    [manager GET:[urlString absoluteString ]parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSArray *response = [responseObject objectForKey:@"results"];
        if (response.count == 0) return;
        NSDictionary *geo = [response[0] objectForKey:@"geometry"];
        NSDictionary *location = [geo objectForKey:@"location"];

        pt.lat = [[location objectForKey:@"lat"] doubleValue];
        pt.lng = [[location objectForKey:@"lng"] doubleValue];
        datalist[indx] = pt;
        NSLog([NSString stringWithFormat:@"%%d \n"], indx);

        // Calling the method that started the call again
        [self loadLatLong];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error");
    }];
}

虽然代码看起来是递归的,但是递归是没有的。当 AFHTTPRequestOperationManager 异步调用完成块时,对 [self loadLatLong] 的调用发生在不同的上下文中。发起请求的 loadLatLong 方法的调用此时已离开调用堆栈,因此调用不是递归的。

代码在加载所有记录之前停止的原因是这个错误检查行:

if (response.count == 0) return;

看起来第 70 个响应没有数据 - 可能是因为 Google 没有 datalist[70] 点的记录。此时代码看到 response.count 为零,而 returns 没有调用 [self loadLatLong].

您可以通过将 if (response.count == 0) return; 替换为

来解决此问题
if (response.count == 0) {
    [self loadLatLong];
    return;
}