0

我遇到了最奇怪的问题,它正在引起我的注意。我在 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

任何人都可以提供任何帮助,我会很感激,因为我被迷惑了:)

4

2 回答 2

0

当您调用 [self reverseGeocode] 时;其余的 handleLongPress 将继续运行,而无需等待 reverseGeocode 完成。这就是为什么您看到打印函数以您不期望的顺序被调用的原因。

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

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

于 2013-05-21T16:14:29.733 回答
0

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

异步与同步执行,它的真正含义是什么?

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

您应该仅在调用 reverseGeocodeLocation 的完成块之后放置新的出生地图钉,例如在完成块内,以确保在放置图钉之前首先获得地标数据。或者您可以只更新完成块内新添加的 pin 的字幕。

[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-21T16:16:18.407 回答