Делегат CLLocationManager не вызывается

Я использую CLLocationManager на устройстве, и методы делегата не вызываются. Вот мой код (я вижу, что класс тоже не освобождается):

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@interface CurrentLocation : NSObject <CLLocationManagerDelegate> {
    CLLocationManager *locationManager;

}
@property (nonatomic, retain) CLLocationManager *locationManager;  

@end

#import "CurrentLocation.h"
#import "SBJson.h"
@implementation CurrentLocation
@synthesize locationManager;

- (id)init
{
    self = [super init];
    if (self) {
        NSLog(@"Initialized");
        locationManager = [[[CLLocationManager alloc] init] autorelease];
        locationManager.delegate = self;
        [locationManager startUpdatingLocation];
        BOOL enable = [CLLocationManager locationServicesEnabled];
        NSLog(@"%@", enable? @"Enabled" : @"Not Enabled");
    }

    return self;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
    NSLog(@"A");
    NSString *stringURL = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=true", newLocation.coordinate.latitude, newLocation.coordinate.longitude];
    NSLog(@"%@", stringURL);

    NSURL *url = [NSURL URLWithString:stringURL];

    NSData *data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url] returningResponse:nil error:nil];

    SBJsonParser *parser = [[SBJsonParser alloc] init];
    NSDictionary *dict = [parser objectWithData:data];
    NSLog(@"%@", dict);
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"B");
}

- (void)dealloc {
    NSLog(@"Dealloc called");
    [super dealloc];
    [locationManager release];
}

@end

В логе вижу:

2011-10-02 19:49:04.095 DixieMatTracker[1404:707] Initialized
2011-10-02 19:49:04.109 DixieMatTracker[1404:707] Enabled

Что я делаю неправильно? Спасибо


person 0xSina    schedule 02.10.2011    source источник
comment
Как определяется свойство locationManager?   -  person    schedule 03.10.2011
comment
Вряд ли что-то изменится, но я видел и более странные вещи. Поместите self.locationManager (для доступа к свойству). Без себя он обращается к резервной переменной, не сохраняя (как вы автоматически выпустили).   -  person Daryl Teo    schedule 03.10.2011
comment
@PragmaOnce Это assign, retain, что? Попробуйте вместо этого использовать self.locationManager. @Daryl Teo Я согласен, это, вероятно, проблема, поскольку locationManager будет выпущен автоматически.   -  person    schedule 03.10.2011
comment
[super dealloc] следует вызывать в конце пользовательской реализации dealloc, а не сначала.   -  person Leslie Godwin    schedule 01.09.2015


Ответы (3)


Вы используете locationManager ivar, а не свойство; это означает, что CLLocationManager не сохраняется и будет освобожден, когда вы его автоматически освободите. Используйте self.locationManager:

self.locationManager = [[[CLLocationManager alloc] init] autorelease];
person Community    schedule 03.10.2011
comment
Не могу поверить, что я этого не уловил... :(. Спасибо. - person 0xSina; 03.10.2011

Я бы посоветовал вам проверить управление памятью в вашем экземпляре CLLocationManager.

Напишите так:

#import "CurrentLocation.h"
#import "SBJson.h"
@implementation CurrentLocation
@synthesize locationManager;

- (id)init
{
    self = [super init];
    if (self) {
        NSLog(@"Initialized");
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self;
        [locationManager startUpdatingLocation];
        BOOL enable = [CLLocationManager locationServicesEnabled];
        NSLog(@"%@", enable? @"Enabled" : @"Not Enabled");
    }

    return self;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
    NSLog(@"A");
    NSString *stringURL = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=true", newLocation.coordinate.latitude, newLocation.coordinate.longitude];
    NSLog(@"%@", stringURL);

    NSURL *url = [NSURL URLWithString:stringURL];

    NSData *data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url] returningResponse:nil error:nil];

    SBJsonParser *parser = [[SBJsonParser alloc] init];
    NSDictionary *dict = [parser objectWithData:data];
    NSLog(@"%@", dict);
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"B");
}

- (void)dealloc {
    NSLog(@"Dealloc called");
    [super dealloc];
    [locationManager release];
}

@end

Делегат не вызывается, так как объект CLLocationManager освобождается до того, как он сможет предоставить ответ на запрос местоположения. Это вызвано авторелизом в вашем коде.

Кроме того, если используется autorelease, было бы ошибкой вручную освобождать его в Dealloc. Это может привести к неожиданным сбоям.

Приведенное выше решение делает это «вручную», выделяя CLLocationManager в init и освобождая его в Dealloc.

person Wizz    schedule 03.10.2011
comment
Ух ты. это сработало. До сих пор не понимаю, почему экземпляр CLLocationManager был освобожден... Я автоматически выпускаю, а затем использую обвинитель, чтобы сохранить его. В любом случае, большое спасибо. - person 0xSina; 03.10.2011
comment
Это не решает основной проблемы: свойство не используется. - person ; 03.10.2011
comment
Использование свойства не запрашивалось. Кстати, это именно то, что происходит, если свойство было определено как сохранение и к нему правильно обращались с помощью self.locationManager - person Wizz; 03.10.2011

В моем случае это было из-за того, что мое устройство не могло определить местоположение - пока я оставался в помещении, сигнал GPS был недоступен, а Wi-Fi также был отключен, поэтому менеджер местоположения просто не смог получить данные о местоположении, а делегату так и не позвонили.

После того, как я подключил wi-fi, все заработало (думаю, в этом случае перемещение на улицу тоже должно помочь, но иногда это не очень удобно :) )

person vir us    schedule 22.03.2015