2014-01-16 30 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