CLLocationManager падает при выпуске, но почему? - PullRequest
4 голосов
/ 24 марта 2011

Это может быть один из тех глупых вопросов, когда, когда указано решение, вы чувствуете себя довольно глупо, задаваясь вопросом, как вы его не видели, но я не могу понять, почему эта часть моего приложения дает сбой EXC_BAD_ACCESS (и без трассировки стека).

У меня есть CLLocationManager * locationManager (ivar, объявленный в файле интерфейса), который создается на viewDidLoad, если locationServices включен:

- (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];    
}

Таким образом, диспетчер местоположений начинает обновлять местоположение, и каждый раз, когда обнаруживается обновление, вызывается метод делегата, приведенный ниже, где я проверяю, должен ли я установить тайм-аут или продолжить поиск желаемой точности:

#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];
}

Если позиция заблокирована, этот метод называется:

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

Если время ожидания истекло, этот метод называется:

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

Проблема в любом случае (тайм-аутили заблокирован), я получаю вывод NSLog в консоли, а затем через 2 секунды приложение вылетает ??

Интересно, что, если я закомментирую мою строку [locationManager release]..., все работает нормально, но ПОЧЕМУ?Кроме того, если я переместу [locationManager release] к моему dealloc методу, тоже не произойдет сбоев!

Я что-то упустил здесь?

Спасибо!

Рог

Ответы [ 2 ]

8 голосов
/ 24 марта 2011

У меня была та же проблема, и, вероятно, есть некоторые проблемы в недрах CLLocationManager. Исправлено:

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

и в discardLocationManager сделать:

- (void) discardLocationManager
{

  locationManager.delegate = nil;
  [locationManager release];

}
3 голосов
/ 13 июля 2011

Вы освобождаете экземпляр CLLocationManager из метода обратного вызова, что не может быть хорошей идеей.

CLLocationManager вызывает ваши обратные вызовы locationManager:didUpdateToLocation:fromLocation и т. Д. Если вы освобождаете менеджер местоположенияНапример, вы в основном освобождаете объект, который только что вызвал вас.Плохая идея.Вот почему приложение аварийно завершает работу.

Вместо выпуска экземпляра диспетчера местоположений вы можете автоматически выпустить его.

Sargon

...