释放MKReverseGeocoder会让我的应用程序崩溃!

时间:2011-04-18 15:32:45

标签: ios4 release 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并且......它不会崩溃! WTF?

1 个答案:

答案 0 :(得分:0)

你应该用解决方案引用堆栈溢出中的另一个帖子:

cllocation and mkreversegeocoder