以下是我正在使用的代码片段。
我有一个名为x_locator
的模型。当我多线程化模型时,maps.google.com会返回620个错误(请求太多太快),但是当我将模型留在主线程上时,它工作正常...只有UI被锁定,而请求正在进行
-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) addressStr {
NSString *urlStr = [NSString stringWithFormat:@"http://maps.google.com/maps/geo? q=%@&output=csv",
[addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlStr]];
NSArray *items = [locationStr componentsSeparatedByString:@","];
double lat = 0.0;
double lon = 0.0;
if([items count] >= 4 && [[items objectAtIndex:0] isEqualToString:@"200"]) {
lat = [[items objectAtIndex:2] doubleValue];
lon = [[items objectAtIndex:3] doubleValue];
}
else {
NSLog(@"Address, %@ not found: Error %@",addressStr, [items objectAtIndex:0]);
}
CLLocationCoordinate2D location;
location.latitude = lat;
location.longitude = lon;
return location;
}
编辑:以下是我尝试使用GCD的方法......这是我的ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//set any delegates
self.locationManager.delegate = self;
[locationManager startUpdatingLocation];
fuelMapView.showsUserLocation = YES;
[self setInitialRegion];
locationManager.distanceFilter = 100;
//create the model
x_locator = [[Locator alloc]init];
x_locator.delegate = self;
dispatch_queue_t finder = dispatch_queue_create("Locator", NULL);
//if I do this, only some of the locations are found. If I leave it on the main thread, all locations are found.
dispatch_async(finder, ^{
[x_locator getUsersZipUsingLocation:[locationManager location]];
});
}
所有getUsersZipUsingLocation:
所做的是使用反向地理编码获取用户邮政编码,然后调用另一个检索地址数组的方法(根据用户zip),最后将每个地址转换为坐标使用-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) addressStr
编辑2: 由于人们可能会失去问题的焦点并继续判断我的编码的优雅,我非常犹豫是否完整地发布代码....
无论如何......在我调用方法-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) addressStr
之前,我必须将地址组合成一个我可以作为变量addressStr
传递的形式。地址分成几部分,所以我组装了各个部分然后继续从网址中获取数据......
NSString *urlStr = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv",
[addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
返回数据后,我说[NSThread sleepForTimeInterval:0.05];
并接下来的请求。
感谢您的评论和时间:)
答案 0 :(得分:2)
首先,getLocationFromAddressString:
不应以get
为前缀;尝试download
或retrieve
或只是省略它(约定)。
其次,发布有关如何实际进行并发呼叫的详细信息。你有多少请求?
“太多请求太快”听起来很精确;你需要限制在远程服务器上抛出请求的速度。
我过去曾使用信号量来限制并发性。
Grand Central Strategy for Opening Multiple Files
所有getUsersZipUsingLocation:确实是使用用户邮政编码 反向地理编码,然后它调用另一个检索 地址数组(根据用户zip),最后是每个地址 这些地址使用转换为坐标位置 - (CLLocationCoordinate2D)getLocationFromAddressString:(NSString *)addressStr
通过以下方式调用:
dispatch_async(finder, ^{
[x_locator getUsersZipUsingLocation:[locationManager location]];
});
首先,您现在有一个异步调用来加载该信息。因此,毫不奇怪,只找到了“一些”物品。一旦你转向异步,你必须使用某种通知机制来指示加载何时完成。
假设usersZipUsingLocation:
是同步的,您可以:
dispatch_async(finder, ^{
[x_locator getUsersZipUsingLocation:[locationManager location]];
[self yoManILoadedTheGoodsDealWithTheUpdate];
});
但这仍然没有解释你的620.那620表示你同时(或几乎如此)发出一堆请求。上述任何一项都没有声称的50毫秒延迟。
所以...这个故事似乎还有更多! :)
仍然不清楚为什么要达到API请求限制。
你真的不应该使用睡眠机制来推迟这些事情。相反,如果绝对必要,使用信号量模式的组合来控制飞行请求中的同时#(最好使用系统的异步加载API)和基于计时器的延迟。这会将所有延迟相关的东西推送到系统而没有保证的线程合同(根据睡眠线程的要求)。