在 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;
}
我正在尝试修复从 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;
}