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?