发布 MKReverseGeocoder 会使我的应用程序崩溃!
我需要知道我的用户来自哪里,所以我制作了一个小的单例对象来获取坐标并使用 Mapkit 来获取我需要的国家/地区代码。
这是我的头文件:
#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 并且......它不会崩溃! 搞什么?
I need to know where my users are from, so I made a little singleton object which gets the coordinates and uses mapkit to get the country code I need.
Here's my header file:
#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
And the implementation:
#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
Well, calling stopGeoCoder method makes my app crash, even calling it via performSelectorOnMainThread...
The problem is in these lines:
if (geoCoder != nil)
{
[geoCoder cancel];
[geoCoder release];
geoCoder = nil;
}
It seems like MKReverseGeocoder become really angry when I try to release it!
I get the crash only on the "didFail" method.
Actually, when it finds the placemark, another class will get the notification, does something and call stopGeocoder and... it doesn't crash!
WTF?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该参考堆栈溢出中的另一篇文章及其解决方案:
cllocation 和 mkreversegeocoder
you should refer to another post in stack overflow with the solution:
cllocation and mkreversegeocoder