2

我正在尝试以新位置作为通知对象发送位置更新。当我这样做时,当我尝试从通知中访问数据时收到“EXC_BAD_ACCESS”错误。如果我执行“po location”,我会看到数据,但我不清楚为什么我无法获取它。设置观察者时,我也尝试将对象参数分配给成员变量,但从未调用 locationUpdate。

这是我的代码(请注意启用了 ARC):

// 位置控制器.h

@protocol LocationDelegateProtocol
@required
    - (void)locationUpdate:(CLLocation *)location;
@end

@interface LocationController : NSObject <CLLocationManagerDelegate> {
    CLLocationManager *locationManager;
    id delegate;
}

@property(nonatomic, retain) CLLocationManager *locationManager;
@property(nonatomic, strong) id delegate;

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;

+ (LocationController *)sharedInstance; // this class is a singleton

@end

// 位置控制器.m

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    [Notification locationChanged:newLocation];
}

// 通知.h

@interface Notification : NSObject
    + (void)locationChanged:(CLLocation *)newLocation;
@end

extern NSString *const kLocationChanged;

// 通知.m

NSString *const kLocationChanged = @"NewLocation";

[[NSNotificationCenter defaultCenter] postNotificationName:kLocationChanged object:newLocation];

// ViewController.h

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, LocationDelegateProtocol> {
    ...
}
...
- (void)locationUpdate:(CLLocation *)location;

@end

// ViewController.m

- (void)setupNotifications {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(locationUpdate:) name:kLocationChanged object:nil];
    // I've tried setting object to a member var "CLLocation *objectFromNotification", but then locationUpdate() is never called.
}

- (void)locationUpdate:(NSNotification *)notification {    
    CLLocation *location = (CLLocation *) [notification object];
    // program receives signal "EXC_BAD_ACCESS" when executing NSLog below.  I can see data inside location when I execute "po location".
    NSLog(@"latitude = %@, longitude = %@",location.coordinate.latitude, location.coordinate.longitude); 
4

2 回答 2

4

将 NSLog 中的格式说明符从 %@ 更改为 %f。您正在尝试将浮点值作为对象访问!

于 2012-02-12T17:27:39.700 回答
2

NSNotifications与他们一起准备一本字典userInfo,您可以在其中放置要与通知一起发送的信息。

我将修复你的代码有点倒退,所以请耐心等待。您确实没有使用 NSNotification 类,因为它通常(或打算)使用。

为了解决这种情况,我们必须做很多事情。post的objectNSNotification是发布 的对象NSNotification,而不是您要与它一起传递的对象。

CLLocation对象添加到字典中,并将其作为userInfo字典传递。您也没有理由使用这种自定义通知类的东西。所以你可以摆脱Notification.hNotification.m

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    NSString *const kLocationChanged = @"NewLocation";
    NSDictionary *locationDict = [NSDictionary dictionaryWithObject:newLocation forKey:@"Location"];
    [[NSNotificationCenter defaultCenter] postNotificationName:kLocationChanged object:nil userInfo:locationDict];
}

所以现在我们将位置信息与通知一起发布。接下来,在收到通知时进行处理。

- (void)locationUpdate:(NSNotification *)notification {    
    CLLocation *location = [[notification userInfo] valueForKey:@"Location"];

    NSLog(@"latitude = %f, longitude = %f",location.coordinate.latitude, location.coordinate.longitude);
}

此外,将您的视图控制器标题更改为以下内容:

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, LocationDelegateProtocol> {
    ...
}
...
- (void)locationUpdate:(NSNotification *)notif;

@end
于 2012-02-12T18:01:33.290 回答