gpt4 book ai didi

iphone - 使用调度队列进行 Google 地理编码的效率 - 如何改进 - iPhone

转载 作者:行者123 更新时间:2023-12-03 21:18:28 25 4
gpt4 key购买 nike

我的应用程序中有一个 Google map View ,其中通过地理编码填充了图钉。我使用下面的代码创建一个调度队列,然后向 Google 查询我的应用程序中每个地点的经度和纬度。

问题是,虽然下面的代码在一定程度上可以工作,但它似乎在第一次运行时错过了很大一部分项目。这些项目将按照下面的代码添加到数组“failedLoad”中。

目前,我正在运行第二种方法来添加 failedLoad 中的位置,每当调用 ViewDidLoad 方法时都会调用该方法。然而,这是一个糟糕的解决方案,因为即使在运行第二个方法之后,failedLoad中仍然有项目,而且我更希望加载所有引脚而不依赖于ViewDidLoad(仅当用户点击引脚然后返回时才调用它)从显示的详细 View 屏幕中)。

任何人都可以提出改进此流程的好方法吗?

谢谢

-(void)displayPlaces {

for (PlaceObject *info in mapLocations) {

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^

{

// GET ANNOTATION INFOS
NSString * addressOne = info.addressOne;
NSString * name = info.name;
NSString * postCode = info.postCode;

NSString * addressTwo = [addressOne stringByAppendingString:@",London,"];
NSString * address = [addressTwo stringByAppendingString:postCode];

NSError * error;

NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString ] encoding:NSASCIIStringEncoding error:&error];
NSArray *listItems = [locationString componentsSeparatedByString:@","];

double latitude = 0.0;
double longitude = 0.0;

if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];

}

else {

NSLog(@"Error %@",name);
[failedLoad addObject : info];

}

CLLocationCoordinate2D coordinate;
coordinate.latitude = latitude;
coordinate.longitude = longitude;
MyLocation *annotation = [[[MyLocation alloc] initWithName:name address:address coordinate:coordinate] autorelease];

dispatch_sync(dispatch_get_main_queue(), ^{

// ADD ANNOTATION
[mapViewLink addAnnotation:annotation];

});

});
}

最佳答案

GCD 很棒,但如果 SDK 已经为此提供了异步 API,则您不应该永远使用线程技术。在您的情况下,永远不要使用stringWithContentsOfURL:,因为它是同步和阻塞代码(这可能就是您切换到使用GCD在后台进行操作的原因),而NSURLConnection 有一个异步 API。 当您需要执行任何网络请求时,请始终使用此异步 API

出于多种原因,这更好:

  • 其中之一是,它是 SDK 中已为此设计的 API(即使您可能需要创建一个类似 MyGeocoder 的类来发送请求、处理响应、解析它并返回以异步方式获取值)
  • 但更喜欢异步 API(而不是使用同步 stringWithContentsOfURL + GCD)的最重要原因是 NSURLConnectionNSRunLoop 集成 并安排在运行循环上检索套接字数据,避免为此创建大量无用的线程(如果在不严格需要的地方使用线程,则线程是邪恶的)。
  • 最后,由于 NSURLConnection 生命周期由 RunLoop 本身处理,因此委托(delegate)方法已在主线程上调用。

GCD 总是比直接使用 NSThreads 更好,但是对于 SDK 中已经做好的事情使用 Runloop 调度,尤其是 NSURLConnections 总是在性能方面更好(避免线程调度问题)、多线程问题等等。

<小时/>

[编辑]例如,如果您不想自己实现该类,则可以使用我的示例 OHURLLoader类并以这种方式使用它:

NSString* urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL* url = [NSURL URLWithString:urlString];
NSURLRequest* req = [NSURLRequest requestWithURL:url];

OHURLLoader* loader = [OHURLLoader URLLoaderWithRequest:req];
[loader startRequestWithCompletion:^(NSData* receivedData, NSInteger httpStatusCode) {
NSString* locationString = loader.receivedString;
NSArray *listItems = [locationString componentsSeparatedByString:@","];
... etc ...
// this callback / block is executed on the main thread so no problem to write this here
[mapViewLink addAnnotation:annotation];
} errorHandler:^(NSError *error) {
NSLog(@"Error while downloading %@: %@",url,error);
}];

关于iphone - 使用调度队列进行 Google 地理编码的效率 - 如何改进 - iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7628464/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com