2011-04-18 2 views
0

필자는 사용자가 누구인지 알아야하므로 조그만 싱글 톤 객체를 만들어 좌표를 얻고 필요한 국가 코드를 얻기 위해 mapkit을 사용합니다.MKReverseGeocoder를 해제하면 앱이 다운됩니다!

#import <Foundation/Foundation.h> 
#import <CoreLocation/CoreLocation.h> 
#import <MapKit/MapKit.h> 

#define TW_GEO_CODER_CHANGED_STATE @"TW_GEO_CODER_CHANGED_STATE" 

@interface TWGeoCoder : NSObject <CLLocationManagerDelegate, MKReverseGeocoderDelegate> 
{ 
    CLLocationManager *locationManager; 
    MKReverseGeocoder *geoCoder; 

    NSString *currentCountryIsoCode; 
} 

+ (TWGeoCoder*) sharedTWGeoCoder; 

-(void) startGeoCoder; 
-(void) stopGeoCoder; 


@property (nonatomic, retain) NSString *currentCountryIsoCode; 

@end 

및 구현 :

여기 내 헤더 파일의

#import "TWGeoCoder.h" 

@implementation TWGeoCoder 


static TWGeoCoder* _singleton; 

+ (TWGeoCoder*) sharedTWGeoCoder 
{ 
    @synchronized([TWGeoCoder class]) 
    { 
     if (_singleton == nil) 
     { 
      _singleton = [[TWGeoCoder alloc] init]; 
     } 
    } 
    return _singleton; 
} 


- (void)startGeoCoder 
{ 
    if (locationManager == nil) 
    { 
     locationManager = [[CLLocationManager alloc] init]; 
    } 
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    locationManager.purpose = NSLocalizedString(@"#LocalizationPurpose",nil); 
    [locationManager startUpdatingLocation]; 
} 

- (void) stopGeoCoder 
{    
    if (geoCoder != nil) 
    { 
     [geoCoder cancel]; 
     [geoCoder release]; 
     geoCoder = nil; 
    } 

    if (locationManager != nil) 
    { 
     [locationManager stopUpdatingLocation]; 
     [locationManager release]; 
     locationManager = nil; 
    } 
} 


#pragma mark - 
#pragma mark locationManager Delegate 

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    if (geoCoder == nil) 
    { 
     geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; 
    } 

    geoCoder.delegate = self; 
    [geoCoder start];  
} 


- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{ 
    NSLog(@"locationManager:%@ didFailWithError:%@", manager, error); 
    [self stopGeoCoder]; 
} 



#pragma mark - 
#pragma mark reverseGeocoder Delegate 

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark 
{ 

    self.currentCountryIsoCode = placemark.countryCode; 

    [[NSNotificationCenter defaultCenter] postNotificationName:TW_GEO_CODER_CHANGED_STATE 
                 object:self]; 
} 


- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error 
{ 
    NSLog(@"reverseGeocoder:%@ didFailWithError:%@", geocoder, error); 
    [self stopGeoCoder];  
} 


#pragma mark - 
#pragma mark Synthesizes 

@synthesize currentCountryIsoCode; 

@end 

글쎄, stopGeoCoder 메소드를 호출하는 경우에도 performSelectorOnMainThread 통해 호출, 내 응용 프로그램 충돌하게 ...

문제는 다음 줄에 있습니다.

if (geoCoder != nil) 
    { 
     [geoCoder cancel]; 
     [geoCoder release]; 
     geoCoder = nil; 
    } 

MKReverseGeocoder가 출시 될 때 정말 화가 났던 것 같습니다! "didFail"메소드에서만 크래시가 발생합니다. 실제로 장소 표시를 찾으면 다른 클래스가 알림을 받고 뭔가를 수행하고 stopGeocoder를 호출하여 충돌이 발생하지 않습니다! WTF?

답변