我遇到了一个最奇怪的问题,而且我正在努力。我在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
任何人都可以帮忙提供任何帮助我会很感激,因为我很喜欢这个:)
答案 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];
}
];
}