传递给NSNotification的访问对象是什么?

23

我有一个发布NSDictionary的NSNotification:

 NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                                          anItemID, @"ItemID",
                                          [NSString stringWithFormat:@"%i",q], @"Quantity",
                                          [NSString stringWithFormat:@"%@",[NSDate date]], @"BackOrderDate",
                                          [NSString stringWithFormat:@"%@", [NSDate date]],@"ModifiedOn",
                                          nil];

                    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"InventoryUpdate" object:dict]];

我如何订阅并从此NSDictionary获取信息?

在我的viewDidLoad中,我有:

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

以及类中的一个方法:

- (void)recieveInventoryUpdate:(NSNotification *)notification {
    NSLog(@"%@ updated", [notification userInfo]);
}

当然会记录null值。


Swift版本 - Juan Boero
8个回答

34

这是一个名为[notification object]的通知对象。

你还可以使用notificationWithName:object:userInfo:方法发送用户信息。


9
Object 不应作为传递通知数据的存储方式。它应该作为通知的发送者,这样您就可以确定是什么类型的对象发送了通知并相应地采取行动。在此处使用 notificationWithName:object:userInfo: 是正确的方法。 - ColdLogic

15

Object是发布通知的对象,而不是存储对象以便您可以访问它的方式。用户信息是您想要与通知一起保存的信息存储位置。

[[NSNotificationCenter defaultCenter] postNotificationName:@"Inventory Update" object:self userInfo:dict];

然后注册通知。该对象可以是您的类,也可以是nil,以仅接收此名称的所有通知。

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

接下来在你的选择器中使用它

- (void)recieveInventoryUpdate:(NSNotification *)notification {
    NSLog(@"%@ updated", [notification userInfo]);
}

3
很简单,见下文。
- (void)recieveInventoryUpdate:(NSNotification *)notification {
    NSLog(@"%@ updated",notification.object); // gives your dictionary 
    NSLog(@"%@ updated",notification.name); // gives keyname of notification

}

如果访问notification.userinfo,它将返回null


2
你的方法不正确。你需要使用以下代码:
-(id)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)userInfo

并将字典传递给最后一个参数。您的“object”参数是发送通知的对象,而不是字典。


2

Swift:

// Propagate notification:
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: ["info":"your dictionary"])

// Subscribe to notification:
NotificationCenter.default.addObserver(self, selector: #selector(yourSelector(notification:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)

// Your selector:
func yourSelector(notification: NSNotification) {
    if let info = notification.userInfo, let infoDescription = info["info"] as? String {
            print(infoDescription)
        } 
}

// Memory cleaning, add this to the subscribed observer class:
deinit {
    NotificationCenter.default.removeObserver(self)
}

1

通知中的object应该是发送者,在您的情况下,字典实际上并不是发送者,它只是信息。任何要与通知一起发送的辅助信息都应该随userInfo字典一起传递。请按如下方式发送通知:

NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                                      anItemID, 
                                      @"ItemID",
                                      [NSString stringWithFormat:@"%i",q], 
                                      @"Quantity",
                                      [NSString stringWithFormat:@"%@", [NSDate date]], 
                                      @"BackOrderDate",
                                      [NSString stringWithFormat:@"%@", [NSDate date]],
                                      @"ModifiedOn",
                                      nil];

[[NSNotificationCenter defaultCenter] postNotification:
        [NSNotification notificationWithName:@"InventoryUpdate" 
                                      object:self 
                                    userInfo:dict]];

然后像这样接收它,以良好的方式获得您想要的行为:

- (void)recieveInventoryUpdate:(NSNotification *)notification {
    NSLog(@"%@ updated", [notification userInfo]);
}

需要注册通知。只是你遗漏了一点小事,:P - ColdLogic
@ColdLogic:没错。我故意省略了那个信息,因为原问题已经包含了它,我相信Slee已经理解了 :). - PeyloW

0
更简单的方法是:
-(void)recieveInventoryUpdate:(NSNotification *)notification
{
    NSLog(@"%@ updated",[notification object]);
    //Or use notification.object
}

对我来说有效。


0

简单答案

详细答案

完整代码应该是:

定义

  • 在你的 viewDidLoad 中添加观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(recieveInventoryUpdate:) name:@"InventoryUpdate" object:nil];
  • 并处理通知方法
- (void)recieveInventoryUpdate:(NSNotification *)notification {
    NSLog(@"notification=%@", notification);
    // NSDictionary* yourPassedInDict = notification.userInfo;
    NSDictionary* yourPassedInDict = [notification userInfo];
    NSLog(@"dict=%@", yourPassedInDict);
}

使用方法 = 调用者

  • 发布一个NSDictionary
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
    anItemID, @"ItemID",
    [NSString stringWithFormat:@"%i",q], @"Quantity",
    [NSString stringWithFormat:@"%@",[NSDate date]], @"BackOrderDate",
    [NSString stringWithFormat:@"%@", [NSDate date]],@"ModifiedOn",
    nil];

[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"InventoryUpdate" object:self userInfo:dict]];

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