如何使用postNotificationName:object传递NSDictionary:

时间:2010-11-08 19:31:23

标签: iphone xcode nsdictionary nsnotificationcenter

我正在尝试使用NSNotificationCenter将NSDictionary表单UIView传递给UIViewController。字典在发布通知时工作正常,但在接收方法中,我无法访问字典中的任何对象。

以下是我创建字典并发布通知的方式......

itemDetails = [[NSDictionary alloc] initWithObjectsAndKeys:@"Topic 1", @"HelpTopic", nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"HotSpotTouched" object:itemDetails];

在UIViewController中,我正在设置观察者......

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(hotSpotMore:)
                                             name:@"HotSpotTouched"
                                           object:nil];

出于测试目的,hotSpotMore看起来像这样......

- (void)hotSpotMore:(NSDictionary *)itemDetails{
      NSLog(@"%@", itemDetails);
      NSLog(@"%@", [itemDetails objectForKey:@"HelpTopic"]);    
}

第一个NSLog工作正常,显示字典的内容。第二个日志抛出以下异常......

 [NSConcreteNotification objectForKey:]: unrecognized selector sent to instance 0x712b130

我不明白为什么我无法访问传递的字典中的任何对象。

提前感谢您的帮助。

约翰

3 个答案:

答案 0 :(得分:110)

  

第一个NSLog工作正常   字典的内容。该   第二个日志抛出以下内容   例外...

程序试图欺骗你,它看起来就像是你的字典,因为你的字典在通知中。从异常中可以看出,您的对象实际上来自名为NSConcreteNotification的类 这是因为notification-method的参数始终是NSNotification-object。 这将有效:

- (void)hotSpotMore:(NSNotification *)notification {
      NSLog(@"%@", notification.object);
      NSLog(@"%@", [notification.object objectForKey:@"HelpTopic"]);    
}

就像一个提示:对象通常是发送通知的对象,你应该将你的NSDictionary作为userInfo发送。
我认为如果您这样做会改善您的代码:

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:@"HotSpotTouched" object:self userInfo:itemDetails];


- (void)hotSpotMore:(NSNotification *)notification {
      NSLog(@"%@", notification.userInfo);
      NSLog(@"%@", [notification.userInfo objectForKey:@"HelpTopic"]);    
}

object参数用于区分可以发送通知的不同对象 假设您有两个不同的HotSpot对象,它们都可以发送通知。在object中设置addObserver:selector:name:object:时,可以为每个对象添加不同的观察者。使用nil作为对象参数意味着应该接收所有通知,而不管发送通知的对象是什么。

E.g:

FancyHotSpot *hotSpotA;
FancyHotSpot *hotSpotB;

// notifications from hotSpotA should call hotSpotATouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(hotSpotATouched:) name:@"HotSpotTouched" 
       object:hotSpotA]; // only notifications from hotSpotA will be received

// notifications from hotSpotB should call hotSpotBTouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(hotSpotBTouched:) name:@"HotSpotTouched" 
       object:hotSpotB]; // only notifications from hotSpotB will be received

// notifications from all objects should call anyHotSpotTouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(anyHotSpotTouched:) name:@"HotSpotTouched" 
       object:nil]; // nil == “any object”, so all notifications with the name “HotSpotTouched” will be received


- (void)hotSpotATouched:(NSNotification *)n {
    // only gets notification of hot spot A
}

- (void)hotSpotBTouched:(NSNotification *)n {
    // only gets notification of hot spot B
}

- (void)anyHotSpotTouched:(NSNotification *)n {
    // catches all notifications
}

答案 1 :(得分:4)

这是使用NSNotification传递词典数据的最佳方式。

发布通知:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"Put Your Notification Name" object:self userInfo:"Pass your dictionary name"];

添加Observer以处理通知。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mydictionaryData:)  name:@"Put Your Notification Name" object:nil];

放置通知处理程序方法。

- (void)mydictionaryData::(NSNotification*)notification{
   NSDictionary* userInfo = notification.userInfo;
   NSLog (@"Successfully received test notification! %@", userInfo);}

我希望,此解决方案可以帮助您

答案 2 :(得分:3)

马蒂亚斯谈论的方法和我认为你应该使用的方法是

postNotificationName:object:userInfo:

其中object是sender,userInfo是你的字典。