我遇到了最奇怪的问题,这让我陷入了困境。我在Singleton中设置的一个全局变量从它所设置的函数中正确地报告,然后从下一个函数(这是我需要访问它的地方)中作为NULL报告,但是从另一个视图中正确!因此,变量是正确设置的,但它在某个函数中没有行为。还有一个奇怪的错误警告是由违规行(我在*之间标记)生成的。
警告是:
Property access result unused - getters should not be used for side effects.很抱歉代码很乱。我在做原型和学习,所以这是我从网络上学到的东西的混合。代码所做的是识别地图视图上的一个长点击,然后在该位置放置一个引脚(同时记录位置),而我正在尝试使用地理代码来显示该位置的地址。
第一项职能如下:
- (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如果有人愿意帮忙,我会很感激的,因为我被骗了:)
发布于 2013-05-21 16:16:18
方法reverseGeocodeLocation:completionHandler:是异步执行的,这意味着它将在完成之前移到下一行。
Asynchronous vs synchronous execution, what does it really mean?
它是异步调用的,因为方法reverseGeocodeLocation:completionHandler:可能需要一些时间来完成它,并且当它完成时,将调用完成块。
您应该只在调用reverseGeocodeLocation的完成块之后(例如,在完成块内)放置新的诞生地引脚,以确保在放置pin之前先获得placemark数据。或者,您可以只更新完成块内新添加的引脚的字幕。
[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];
}
];
}发布于 2013-05-21 16:14:29
当您调用self reverseGeocode时,handleLongPress的其余部分将继续运行,而无需等待reverseGeocode完成。这就是为什么您看到打印函数按您预期的顺序调用的原因。
[self performSelectorOnMainThread:@selector(reverseGeocode) withObject:nil waitUntilDone:YES];如果handleLongPress在主线程上运行,那么上面的行可以替换self reverseGeocode,并且应该会产生预期的结果。
https://stackoverflow.com/questions/16672114
复制相似问题