CLLocationManager代理未被调用

3
我正在设备上使用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

我做错了什么吗? 谢谢。

locationManager 属性是如何定义的? - user94896
不太可能有所影响,但我见过更奇怪的事情。使用self.locationManager(来访问属性)。如果没有self,它将访问后备变量,而不会保留(因为您已经自动释放)。 - Daryl Teo
1
@PragmaOnce 这是assign还是retain呢?试试使用self.locationManager。@Daryl Teo 我同意,这很可能是问题所在,因为locationManager将被自动释放。 - user94896
在自定义的 dealloc 实现中,应该在最后调用 [super dealloc],而不是首先调用。 - Leslie Godwin
3个回答

6

您正在使用 locationManager 实例变量,而不是属性;这意味着 CLLocationManager 没有被保留,当您释放它时将被销毁。请使用 self.locationManager

self.locationManager = [[[CLLocationManager alloc] init] autorelease];

难以置信我没发现那个错误... :(。谢谢。 - 0xSina

3
我建议您检查CLLocationManager实例的内存管理。
请按照以下方式编写:

我建议您检查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中手动释放会导致意外崩溃,这是一个错误的做法。

上述解决方案通过在init中分配CLLocationManager并在dealloc中释放来手动处理。


哇,好了。仍然不明白CLLocationManager实例为什么会被释放...我正在使用自动释放并使用保留器来保留它。不管怎样,非常感谢。 - 0xSina
1
这并没有解决根本问题:该属性未被使用。 - user94896
未经允许使用该属性。顺便说一句,如果将该属性定义为 retain 并且使用 self.locationManager 正确访问,则会出现这种情况。 - Wizz

0
在我的情况下,这是因为我的设备无法确定位置 - 当我室内时,GPS信号不可用且Wi-Fi已断开,因此位置管理器无法接收任何位置数据并且代理从未被调用。
一旦我连接了Wi-Fi,它就可以工作了(我想在户外移动也应该可以解决这个问题,但有时这种方式并不是很方便 :))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接