开发者

CLLocationManager crashing on release, but why?

开发者 https://www.devze.com 2023-02-19 22:05 出处:网络
This might be one of those silly question where, once a solution is pointed out, makes you feel pretty stupid wondering how you didn\'t see it but I can\'t figure out why this part of my app is crashi

This might be one of those silly question where, once a solution is pointed out, makes you feel pretty stupid wondering how you didn't see it but I can't figure out why this part of my app is crashing with EXC_BAD_ACCESS (and no stack trace).

I have a CLLocationManager *locationManager (ivar declared in interface file) that gets created on viewDidLoad if locationServices is enabled:

- (void)viewDidLoad
{
    [super viewDidLoad];
    if ([CLLocationManager locationServicesEnabled])
    [self findUserLocation];
    ...
}

#pragma mark - Location finder methods

- (void)findUserLocation
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    [locationManager startUpdatingLocation];    
}

So the loca开发者_C百科tion manager starts updating location and each time and update is found, the delegate method below is called, where I check to see if I should time out or continue looking for my desiredAccuracy:

#pragma mark - CLLocationManager delegates

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if ([newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp] > 8)
        [self locationManagerTimeOut];
    else if ((newLocation.horizontalAccuracy <= manager.desiredAccuracy) && (newLocation.verticalAccuracy <= manager.desiredAccuracy))
        [self locationManagerLockedPosition];
}

If a position is locked, this method is called:

- (void)locationManagerLockedPosition
{
    [locationManager stopUpdatingLocation];
    locationManager.delegate = nil;
    [locationManager release], locationManager = nil;
    NSLog (@"add results to view");
}

If it times out, this is the method called:

- (void)locationManagerTimeOut
{
    [locationManager stopUpdatingLocation];
    locationManager.delegate = nil;
    [locationManager release], locationManager = nil;
    NSLog (@"Time out!");
}

Problem is, in either case (time out or locked position), I get the NSLog output in the console and then 2 secs later the app crashes??

Interesting thing is, if I comment out my [locationManager release]... line, everything works fine but WHY? Also if I move the [locationManager release] to my dealloc method, no crashes either!

Am I missing something basic here?

Thanks!

Rog


I had the same issue and there's probably some problem in the depths of CLLocationManager. Fixed by doing:

[locationManager stopUpdatingLocation];
[self performSelector:@selector(discardLocationManager) onThread:[NSThread currentThread] withObject:nil waitUntilDone:NO];

and in discardLocationManager do:

- (void) discardLocationManager
{

  locationManager.delegate = nil;
  [locationManager release];

}


You are release the CLLocationManager instance from within a callback method, which can't be a good idea.

The CLLocationManager calls your callbacks locationManager:didUpdateToLocation:fromLocation etc. If you release the location manager instance, you're basically deallocating the object that just called you. Bad idea. That's why the app crashes.

Instead of releasing the location manager instance, you could autorelease it.

Sargon

0

精彩评论

暂无评论...
验证码 换一张
取 消