加快Google地理编码的addAnnotations?

时间:2011-05-01 19:54:18

标签: iphone objective-c annotations mapkit geocoding

我的应用程序中有以下代码,它通过Google地理编码为mapview添加了许多注释:

for (PlaceObject *info in mapLocations) {

    NSString * addressOne = info.addressOne;
    NSString * name = info.name;

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

    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 {
        //Error handling

    }        

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

}

这是有效的,但是视图显示需要很长时间,因为它似乎要等到数组中的所有对象都已循环通过(大约有80个)。

有没有办法让视图加载,然后在创建时添加引脚?

3 个答案:

答案 0 :(得分:1)

这个怎么样:

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 * address = [addressOne stringByAppendingString:@",London"];

        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 {
            //Error handling

        }        

        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];

        });

    });
}

但请考虑仔细检查此代码。关于保持线程安全并避免EXC_BAD_ACCESS

,你应该做些明确的事情

答案 1 :(得分:0)

此代码在您的应用中执行的位置?

我建议使用NSURLConnection并在收到并解析数据后添加注释。如果您不熟悉NSURLConnection,请查看此处了解更多信息:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html

答案 2 :(得分:0)

是的,您在主(UI)线程中做了长时间工作(从URL净加载)的经典错误。将此工作移至后台线程,然后让主线程添加引脚。这可以通过多种方式,通过创建另一个显式线程,带有块的GCD,或者只是在后台线程中执行performSelector。最简单的方法是在后台执行Selector,然后在有东西添加到map时,在主线程上执行Selector。