首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >地理代码+ MKPointAnnotation玩得不好

地理代码+ MKPointAnnotation玩得不好
EN

Stack Overflow用户
提问于 2013-05-21 14:06:38
回答 2查看 441关注 0票数 0

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

警告是:

代码语言:javascript
复制
Property access result unused - getters should not be used for side effects.

很抱歉代码很乱。我在做原型和学习,所以这是我从网络上学到的东西的混合。代码所做的是识别地图视图上的一个长点击,然后在该位置放置一个引脚(同时记录位置),而我正在尝试使用地理代码来显示该位置的地址。

第一项职能如下:

代码语言:javascript
复制
- (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);

}

上面的函数调用下一个函数:

代码语言:javascript
复制
-(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中的一个之前打印,尽管它(我假设)是第二个执行的!例如,调试输出是:

代码语言:javascript
复制
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

如果有人愿意帮忙,我会很感激的,因为我被骗了:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-21 16:16:18

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

Asynchronous vs synchronous execution, what does it really mean?

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

您应该只在调用reverseGeocodeLocation的完成块之后(例如,在完成块内)放置新的诞生地引脚,以确保在放置pin之前先获得placemark数据。或者,您可以只更新完成块内新添加的引脚的字幕。

代码语言:javascript
复制
[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];
    }
 ];
}
票数 0
EN

Stack Overflow用户

发布于 2013-05-21 16:14:29

当您调用self reverseGeocode时,handleLongPress的其余部分将继续运行,而无需等待reverseGeocode完成。这就是为什么您看到打印函数按您预期的顺序调用的原因。

代码语言:javascript
复制
    [self performSelectorOnMainThread:@selector(reverseGeocode) withObject:nil waitUntilDone:YES];

如果handleLongPress在主线程上运行,那么上面的行可以替换self reverseGeocode,并且应该会产生预期的结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16672114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档