2012-02-12 155 views
2

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

这里是我的代码(注意,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); 

回答

4

改变你的NSLog格式说明从%@到%F 。您正试图将float值作为对象访问!

+0

LOL。我有%f开始,但是我还有其他缺陷,并且正在上课。修复了一些其他缺陷后,我忘了将它改回来。我曾假设我没有解决我原来的问题。感谢您的发现:) – TERACytE 2012-02-12 18:16:42

+0

没问题。有时候,我们错过了小事。 – cocoakomali 2012-02-13 20:44:52

2

NSNotifications有一个与他们的字典叫userInfo,你可以把你要与通知发送信息。

我要解决你的代码有点倒退......所以裸陪我。您确实没有使用NSNotification类,因为它通常(或打算)被使用。我们不得不做很多事情。 NSNotification文章的object值是发布NSNotification的对象,而不是您想要传递的对象。

CLLocation对象添加到字典中,并将其作为userInfo字典传入。这个自定义通知类也没有任何理由。所以,你可以摆脱​​和Notification.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 
+0

我对https://developer.apple上的文档的解释。com/library/mac /#documentation/Cocoa/Reference/Foundation/Classes/nsnotification_Class/Reference/Reference.html是可接受的:“该对象是通知的发布者希望发送给该通知的观察者的任何对象“ – TERACytE 2012-02-12 18:20:18

+0

事实上,你可以做任何你想做的事,那就是做程序员的好处。当您需要更多信息,多条信息或需要知道哪些对象发送了通知时,您当前实施的问题就会出现。来自同一文档的下一行:“该对象是通知的发布者希望发送给该通知的观察者的任何对象(通常是发布通知的对象)。该字典存储其他相关对象(如果有的话) “。 – ColdLogic 2012-02-12 18:44:54