如何使用 NSNotificationCenter 传递对象

发布于 2024-12-12 02:27:00 字数 927 浏览 0 评论 0原文

我试图将一个对象从我的应用程序委托传递到另一个类中的通知接收器。

我想传递整数 messageTotal。现在我有:

在接收器中:

- (void) receiveTestNotification:(NSNotification *) notification
{
    if ([[notification name] isEqualToString:@"TestNotification"])
        NSLog (@"Successfully received the test notification!");
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissSheet) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveTestNotification:) name:@"eRXReceived" object:nil];

在正在执行通知的类中:

[UIApplication sharedApplication].applicationIconBadgeNumber = messageTotal;
[[NSNotificationCenter defaultCenter] postNotificationName:@"eRXReceived" object:self];

但我想将对象 messageTotal 传递给另一个类。

I am trying to pass an object from my app delegate to a notification receiver in another class.

I want to pass integer messageTotal. Right now I have:

In Receiver:

- (void) receiveTestNotification:(NSNotification *) notification
{
    if ([[notification name] isEqualToString:@"TestNotification"])
        NSLog (@"Successfully received the test notification!");
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissSheet) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveTestNotification:) name:@"eRXReceived" object:nil];

In the class that is doing the notification:

[UIApplication sharedApplication].applicationIconBadgeNumber = messageTotal;
[[NSNotificationCenter defaultCenter] postNotificationName:@"eRXReceived" object:self];

But I want to pass the object messageTotal to the other class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

属性 2024-12-19 02:27:00

您必须使用“userInfo”变体并传递一个包含 messageTotal 整数的 NSDictionary 对象:

NSDictionary* userInfo = @{@"total": @(messageTotal)};

NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"eRXReceived" object:self userInfo:userInfo];

在接收端,您可以按如下方式访问 userInfo 字典:

-(void) receiveTestNotification:(NSNotification*)notification
{
    if ([notification.name isEqualToString:@"TestNotification"])
    {
        NSDictionary* userInfo = notification.userInfo;
        NSNumber* total = (NSNumber*)userInfo[@"total"];
        NSLog (@"Successfully received test notification! %i", total.intValue);
    }
}

You'll have to use the "userInfo" variant and pass a NSDictionary object that contains the messageTotal integer:

NSDictionary* userInfo = @{@"total": @(messageTotal)};

NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"eRXReceived" object:self userInfo:userInfo];

On the receiving end you can access the userInfo dictionary as follows:

-(void) receiveTestNotification:(NSNotification*)notification
{
    if ([notification.name isEqualToString:@"TestNotification"])
    {
        NSDictionary* userInfo = notification.userInfo;
        NSNumber* total = (NSNumber*)userInfo[@"total"];
        NSLog (@"Successfully received test notification! %i", total.intValue);
    }
}
剑心龙吟 2024-12-19 02:27:00

在提供的解决方案的基础上,我认为展示一个传递您自己的自定义数据对象的示例可能会有所帮助(我在此处根据问题将其引用为“消息”)。

A 类(发送方):

YourDataObject *message = [[YourDataObject alloc] init];
// set your message properties
NSDictionary *dict = [NSDictionary dictionaryWithObject:message forKey:@"message"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationMessageEvent" object:nil userInfo:dict];

B 类(接收方):

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(triggerAction:) name:@"NotificationMessageEvent" object:nil];
}

#pragma mark - Notification
-(void) triggerAction:(NSNotification *) notification
{
    NSDictionary *dict = notification.userInfo;
    YourDataObject *message = [dict valueForKey:@"message"];
    if (message != nil) {
        // do stuff here with your message data
    }
}

Building on the solution provided I thought it might be helpful to show an example passing your own custom data object (which I've referenced here as 'message' as per question).

Class A (sender):

YourDataObject *message = [[YourDataObject alloc] init];
// set your message properties
NSDictionary *dict = [NSDictionary dictionaryWithObject:message forKey:@"message"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationMessageEvent" object:nil userInfo:dict];

Class B (receiver):

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(triggerAction:) name:@"NotificationMessageEvent" object:nil];
}

#pragma mark - Notification
-(void) triggerAction:(NSNotification *) notification
{
    NSDictionary *dict = notification.userInfo;
    YourDataObject *message = [dict valueForKey:@"message"];
    if (message != nil) {
        // do stuff here with your message data
    }
}
筱武穆 2024-12-19 02:27:00

Swift 5

func post() {
    NotificationCenter.default.post(name: Notification.Name("SomeNotificationName"), 
        object: nil, 
        userInfo:["key0": "value", "key1": 1234])
}

func addObservers() {
    NotificationCenter.default.addObserver(self, 
        selector: #selector(someMethod), 
        name: Notification.Name("SomeNotificationName"), 
        object: nil)
}

@objc func someMethod(_ notification: Notification) {
    let info0 = notification.userInfo?["key0"]
    let info1 = notification.userInfo?["key1"]
}

Bonus(你绝对应该这样做!):

Notification.Name("SomeNotificationName") 替换为 .someNotificationName

extension Notification.Name {
    static let someNotificationName = Notification.Name("SomeNotificationName")
}

替换 "key0""key1"Notification.Key.key0Notification.Key.key1

extension Notification {
  enum Key: String {
    case key0
    case key1
  }
}

为什么我一定要这样做?为了避免代价高昂的拼写错误,请享受重命名、享受查找用法等......

Swift 5

func post() {
    NotificationCenter.default.post(name: Notification.Name("SomeNotificationName"), 
        object: nil, 
        userInfo:["key0": "value", "key1": 1234])
}

func addObservers() {
    NotificationCenter.default.addObserver(self, 
        selector: #selector(someMethod), 
        name: Notification.Name("SomeNotificationName"), 
        object: nil)
}

@objc func someMethod(_ notification: Notification) {
    let info0 = notification.userInfo?["key0"]
    let info1 = notification.userInfo?["key1"]
}

Bonus (that you should definitely do!) :

Replace Notification.Name("SomeNotificationName") with .someNotificationName:

extension Notification.Name {
    static let someNotificationName = Notification.Name("SomeNotificationName")
}

Replace "key0" and "key1" with Notification.Key.key0 and Notification.Key.key1:

extension Notification {
  enum Key: String {
    case key0
    case key1
  }
}

Why should I definitely do this ? To avoid costly typo errors, enjoy renaming, enjoy find usage etc...

无风消散 2024-12-19 02:27:00

Swift 2 版本

正如 @Johan Karlsson 指出的......我做错了。这是使用 NSNotificationCenter 发送和接收信息的正确方法。

首先,我们看一下 postNotificationName 的初始化程序:

init(name name: String,
   object object: AnyObject?,
 userInfo userInfo: [NSObject : AnyObject]?)

source

我们将使用 userInfo 参数传递我们的信息。 [NSObject : AnyObject] 类型是 Objective-C 的继承。因此,在 Swift 领域,我们需要做的就是传入一个 Swift 字典,其中包含从 NSObject 派生的键和可以是 AnyObject 的值。

有了这些知识,我们创建一个字典,将其传递到 object 参数中:

 var userInfo = [String:String]()
 userInfo["UserName"] = "Dan"
 userInfo["Something"] = "Could be any object including a custom Type."

然后我们将字典传递到我们的 object 参数中。

发送者

NSNotificationCenter.defaultCenter()
    .postNotificationName("myCustomId", object: nil, userInfo: userInfo)

接收者类

首先我们需要确保我们的类正在观察通知

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("btnClicked:"), name: "myCustomId", object: nil)   
}
    

然后我们可以接收我们的字典:

func btnClicked(notification: NSNotification) {
   let userInfo : [String:String!] = notification.userInfo as! [String:String!]
   let name = userInfo["UserName"]
   print(name)
}

Swift 2 Version

As @Johan Karlsson pointed out... I was doing it wrong. Here's the proper way to send and receive information with NSNotificationCenter.

First, we look at the initializer for postNotificationName:

init(name name: String,
   object object: AnyObject?,
 userInfo userInfo: [NSObject : AnyObject]?)

source

We'll be passing our information using the userInfo param. The [NSObject : AnyObject] type is a hold-over from Objective-C. So, in Swift land, all we need to do is pass in a Swift dictionary that has keys that are derived from NSObject and values which can be AnyObject.

With that knowledge we create a dictionary which we'll pass into the object parameter:

 var userInfo = [String:String]()
 userInfo["UserName"] = "Dan"
 userInfo["Something"] = "Could be any object including a custom Type."

Then we pass the dictionary into our object parameter.

Sender

NSNotificationCenter.defaultCenter()
    .postNotificationName("myCustomId", object: nil, userInfo: userInfo)

Receiver Class

First we need to make sure our class is observing for the notification

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("btnClicked:"), name: "myCustomId", object: nil)   
}
    

Then we can receive our dictionary:

func btnClicked(notification: NSNotification) {
   let userInfo : [String:String!] = notification.userInfo as! [String:String!]
   let name = userInfo["UserName"]
   print(name)
}
猥琐帝 2024-12-19 02:27:00

Swift 5.1 自定义对象/类型

// MARK: - NotificationName
// Extending notification name to avoid string errors.
extension Notification.Name {
    static let yourNotificationName = Notification.Name("yourNotificationName")
}


// MARK: - CustomObject
class YourCustomObject {
    // Any stuffs you would like to set in your custom object as always.
    init() {}
}

// MARK: - Notification Sender Class
class NotificatioSenderClass {

     // Just grab the content of this function and put it to your function responsible for triggering a notification.
    func postNotification(){
        // Note: - This is the important part pass your object instance as object parameter.
        let yourObjectInstance = YourCustomObject()
        NotificationCenter.default.post(name: .yourNotificationName, object: yourObjectInstance)
    }
}

// MARK: -Notification  Receiver class
class NotificationReceiverClass: UIViewController {
    // MARK: - ViewController Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        // Register your notification listener
        NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotificationWithCustomObject), name: .yourNotificationName, object: nil)
    }

    // MARK: - Helpers
    @objc private func didReceiveNotificationWithCustomObject(notification: Notification){
        // Important: - Grab your custom object here by casting the notification object.
        guard let yourPassedObject = notification.object as? YourCustomObject else {return}
        // That's it now you can use your custom object
        //
        //

    }
      // MARK: - Deinit
  deinit {
      // Save your memory by releasing notification listener
      NotificationCenter.default.removeObserver(self, name: .yourNotificationName, object: nil)
    }




}

Swift 5.1 Custom Object/Type

// MARK: - NotificationName
// Extending notification name to avoid string errors.
extension Notification.Name {
    static let yourNotificationName = Notification.Name("yourNotificationName")
}


// MARK: - CustomObject
class YourCustomObject {
    // Any stuffs you would like to set in your custom object as always.
    init() {}
}

// MARK: - Notification Sender Class
class NotificatioSenderClass {

     // Just grab the content of this function and put it to your function responsible for triggering a notification.
    func postNotification(){
        // Note: - This is the important part pass your object instance as object parameter.
        let yourObjectInstance = YourCustomObject()
        NotificationCenter.default.post(name: .yourNotificationName, object: yourObjectInstance)
    }
}

// MARK: -Notification  Receiver class
class NotificationReceiverClass: UIViewController {
    // MARK: - ViewController Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        // Register your notification listener
        NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotificationWithCustomObject), name: .yourNotificationName, object: nil)
    }

    // MARK: - Helpers
    @objc private func didReceiveNotificationWithCustomObject(notification: Notification){
        // Important: - Grab your custom object here by casting the notification object.
        guard let yourPassedObject = notification.object as? YourCustomObject else {return}
        // That's it now you can use your custom object
        //
        //

    }
      // MARK: - Deinit
  deinit {
      // Save your memory by releasing notification listener
      NotificationCenter.default.removeObserver(self, name: .yourNotificationName, object: nil)
    }




}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文