2014-01-16 27 views
0

我正在尝试将CLGeocoder检索的城市名称成功传递给另一个类的UILabel。首先,CLGecoder级将CLGeocoder城市名称传递给新类UILabel

FindLocation.h

@property (nonatomic, strong) NSString *cityName; 

FindLocation.m - 里法(无效)的LocationManager:(CLLocationManager *)经理...

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 
if (self.isFirstUpdate) { 
    self.isFirstUpdate = NO; 
    return; 
} 

CLLocation *location = [locations lastObject]; 

if (location.horizontalAccuracy > 0) { 
    self.currentLocation = location;} 

CLGeocoder *fgeo = [[CLGeocoder alloc] init]; 

// Reverse Geocode a CLLocation to a CLPlacemark 
[fgeo reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError 
*error){ 
    NSLog(@"%@", location); 

       // Make sure the geocoder did not produce an error 
       // before continuing 
       if(!error){ 
        // Iterate through all of the placemarks returned 
        // and output them to the console 

        for(CLPlacemark *placemark in placemarks){ 
         NSLog(@"%@",[placemark description]); 
         self.cityName = [placemark locality]; 
         NSLog(@"city is %@",cityName); } 

        [self.locationManager stopUpdatingLocation]; 
        [self.delegate findLocationDidGeocodeCityName:self.cityName]; 
       } else { 
        // Our geocoder had an error, output a message 
        // to the console 
        NSLog(@"There was a reverse geocoding error\n%@", 
         [error localizedDescription]); 

而且在我FirstViewController它看起来像这样:

FindLocation *cityname = [[FindLocation alloc] init]; 
    [cityname cityName]; 
    [self.cityLabel setText:(cityname.cityName)]; 
    NSLog(@"CityName is...%@", cityname.cityName); //Log shows CityName is...(null) 

我不知道这里有什么错。既然找到了城市,后面的代码肯定会出错,但我不知道是什么。 NSString - cityName的传递是否实现了错误?

+0

我会在locationManager:didUpdateLocations:方法的开始处设置一个断点,并逐行执行。我想知道它是否只更新一次,并在设置'self.isFirstUpdate = NO'后返回。或者,也许现在只是将'return;'语句注释掉,看看它是否有效。 – atticus

+0

是的,它现在被叫了,但仍然没有印刷城市的标签 – Pierre

+0

可能是一个愚蠢的问题,但是你确定cityLabel在Interface Builder中连接了吗? – atticus

回答

0

我认为问题在于地理编码过程不是即时的。您正在实例化FindLocation,然后立即尝试访问cityName。但是,即使假设您的init方法触发位置更新,地理编码器也需要一点时间才能访问服务器并获得响应。另外,位置管理器不会立即返回一个位置,并且由于它看起来像是地理编码器的起始位置,所以您必须稍等一会。

这里的一个解决方案是在FindLocation上实现委托协议,以便在地理编码完成时通知FirstViewController。事情是这样的:

FindLocation.h

#import <UIKit/UIKit.h> 

@class FindLocation; 
@protocol FindLocationDelegate <NSObject> 
- (void)findLocationDidGeocodeCityName:(NSString *)cityName; 
@end 

@interface FindLocation : NSObject 

@property (weak, nonatomic) id<FindLocationDelegate> delegate; 

@end 

,然后在CLGeocoder completionHandler检索的cityName后:现在

[self.delegate findLocationDidGeocodeCityName:self.cityName]; 

,在FirstviewController.h,表明您符合FindLocationDelegate协议:

@interface FirstViewController : UIViewController <FindLocationDelegate> 

在你的FirstViewCont roller.m,设置委托像这样:

FindLocation *cityName = [[FindLocation alloc] init]; 
cityName.delegate = self; 

,然后也FirstViewController,实现委托方法:

#pragma mark - FindLocation Delegate 

- (void)findLocationDidGeocodeCityName:(NSString *)cityName 
{ 
    [self.cityLabel setText:cityName]; 
} 

还有其他的方法来做到这一点为好,但关键是你必须等到completionHandler运行,然后通知其他感兴趣的对象返回什么。

+0

我设置代理的部分调用了错误:从不兼容类型中分配给id强 – Pierre

+0

您在哪里调用该代码?你可以发布方法让我看看吗? – atticus

+0

我在viewDidLoad中调用该代码。你的意思是什么? – Pierre