如何从NSNotification对象获取数据?

时间:2012-02-12 17:16:50

标签: iphone objective-c xcode ipad nsnotification

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

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

// LocationController.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

// LocationController.m

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

// Notification.h

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

extern NSString *const kLocationChanged;

// Notification.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); 

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

NSNotifications有一个名为userInfo的字典,您可以在其中输入您希望随通知一起发送的信息。

我要修复你的代码有点倒退......对我来说很光鲜。您确实没有使用过NSNotification类,因为它通常(或打算使用)。

要解决这个问题,我们必须做很多事情。 object帖子的NSNotification值是发布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