Speed up addAnnotations from Google Geocoding?

一个人想着一个人 提交于 2019-12-23 04:43:38

问题


I have the following code in my app which adds a number of Annotations to a mapview via Google geocoding:

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

}

This works, however it takes a long time for the view to appear as it seems to wait until all objects in the array have been looped through (there are about 80).

Is there any way to make the view load and then for the pins to be added as they are created ?


回答1:


How about this:

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

        });

    });
}

But please consider to double-check this code. There are definitily things you should do about keeping the threads safe and avoid EXC_BAD_ACCESS.




回答2:


Where is this code executed in your app?

I'd recommend using NSURLConnection and adding the annotations after the data has been received and parsed. Look here for more info, if you're not familiar with NSURLConnection: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html




回答3:


Yea, you are making the classic error of doing long work (net loading from a URL) in the main (UI) thread. Move this work into a background thread and then have the main thread add the pins. This can be in several ways, by creating another explicit thread, GCD with blocks, or just performSelector in background thread. Easiest way is to probably performSelector in background and then when it has something to add to map, performSelector on main thread.



来源:https://stackoverflow.com/questions/5850930/speed-up-addannotations-from-google-geocoding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!