地理编码+ MKPointAnnotation不能很好地播放

时间:2013-05-21 14:06:39

标签: iphone ios geocoding

我遇到了一个最奇怪的问题,而且我正在努力。我在Singleton中设置的全局变量正在从它设置的函数中正确报告,然后在下一个函数中作为NULL (这是我需要访问它的地方),但从另一个视图正确!因此变量被正确设置,但它不在某个函数内表现。还有一个奇怪的错误警告是由违规行(我在 * 之间标记)生成的。

警告是:

Property access result unused - getters should not be used for side effects.

为非常不稳定的代码道歉。我正在进行原型设计和学习,所以这是我从网上拼凑出的东西的混杂。代码的作用是识别mapview上的长按,然后在该位置放置一个引脚(同时记录位置),我正在尝试使用Geocode在引脚位置显示地址。

第一个功能如下:

- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
    return;

CGPoint touchPoint = [gestureRecognizer locationInView:self.fullMapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.fullMapView convertPoint:touchPoint toCoordinateFromView:self.fullMapView];

//save new birthplace in global variable        
globalsSingle.gblBirthplace = touchMapCoordinate;

//place user location and record it
MKUserLocation *location = fullMapView.userLocation;
globalsSingle.gblCurrentLocation = location.coordinate;

//first remove any previous birthplace pin
[self removeAllPinsButUserLocation];

[self reverseGeocode];

//place new birthplace pin
MKPointAnnotation *birthPlacePin = [[MKPointAnnotation alloc] init];
birthPlacePin.coordinate = touchMapCoordinate;
birthPlacePin.title = @"My Birthplace";
**** birthPlacePin.subtitle = @"%@", globalsSingle.gblAddress; ****
[self.fullMapView addAnnotation:birthPlacePin];

NSLog(@"gblAddress = %@", globalsSingle.gblAddress);

}

上面的函数调用下一个:

-(void)reverseGeocode {

CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:globalsSingle.gblBirthplace.latitude     longitude:globalsSingle.gblBirthplace.longitude]; //insert your coordinates

[ceo reverseGeocodeLocation: loc completionHandler:
 ^(NSArray *placemarks, NSError *error) {
     CLPlacemark *placemark = [placemarks objectAtIndex:0];
     //String to hold address
     NSString *locatedAt = [[placemark.addressDictionary  valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];

     // save the address text
     globalsSingle.gblAddress = locatedAt;

    NSLog(@"addressDictionary %@", placemark.addressDictionary);
    NSLog(@"placemark %@",placemark.region);
    NSLog(@"placemark %@",placemark.country);  // Give Country Name
    NSLog(@"placemark %@",placemark.locality); // Extract the city name
    NSLog(@"location %@",placemark.name);
    NSLog(@"location %@",placemark.ocean);
    NSLog(@"location %@",placemark.postalCode);
    NSLog(@"location %@",placemark.subLocality);
    NSLog(@"location %@",placemark.location);
   //Print the location to console
     NSLog(@"I am currently at %@",locatedAt);
     NSLog(@"gblAddress from reverse Geocode = %@", globalsSingle.gblAddress);

    }
 ];
}

甚至更奇怪(对我来说)是来自reverseGeocode内的NSLog都正确打印,但来自第一个函数的NSLog报告为NULL,并且正在从reverseGeocode打印之前,即使它(我假设)正在被执行第二!例如,调试输出为:

2013-05-21 23:41:04.662 Project Name[5659:c07] gblAddress = (null)
2013-05-21 23:41:04.808 Project Name[5659:c07] gblAddress from reverse Geocode = Januária - MG, Brazil

任何人都可以帮忙提供任何帮助我会很感激,因为我很喜欢这个:)

2 个答案:

答案 0 :(得分:0)

当你调用[self reverseGeocode]时; handleLongPress的其余部分将继续运行,无需等待reverseGeocode完成。这就是为什么您看到按照您不期望的顺序调用打印功能的原因。

    [self performSelectorOnMainThread:@selector(reverseGeocode) withObject:nil waitUntilDone:YES];

如果handleLongPress在主线程上运行,则上面的行可以替换[self reverseGeocode]并产生预期的结果。

答案 1 :(得分:0)

方法reverseGeocodeLocation:completionHandler:是异步执行的,这意味着它会在完成之前移到下一行。

Asynchronous vs synchronous execution, what does it really mean?

它是异步调用的,因为方法reverseGeocodeLocation:completionHandler:可能需要一些时间来完成它,并且当它完成时,将调用完成块。

只有在调用reverseGeocodeLocation的完成块之后,例如在完成块内,才应放置新的生成引脚,以确保在放置引脚之前首先获得了地标数据。或者您可以更新完成块内新添加的引脚的字幕。

[ceo reverseGeocodeLocation: loc completionHandler:
 ^(NSArray *placemarks, NSError *error) {
     CLPlacemark *placemark = [placemarks objectAtIndex:0];
     //String to hold address
     NSString *locatedAt = [[placemark.addressDictionary  valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];

     // save the address text
     globalsSingle.gblAddress = locatedAt;

     //place new birthplace pin
     MKPointAnnotation *birthPlacePin = [[MKPointAnnotation alloc] init];
     birthPlacePin.coordinate = globalsSingle.gblBirthplace;
     birthPlacePin.title = @"My Birthplace";
     birthPlacePin.subtitle = globalsSingle.gblAddress;
     [self.fullMapView addAnnotation:birthPlacePin];
    }
 ];
}