我正在尝试将我的应用程序委托中的对象传递给另一个类中的通知接收器。
我想传递整数 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
传递给另一个类。
您必须使用“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);
}
}
在提供的解决方案的基础上,我认为展示一个传递您自己的自定义数据对象的示例可能会有所帮助(我在此处根据问题将其称为“消息”)。
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
}
}
postNotificationName
中的 object
参数应表示发送此通知的参数。
userInfo
参数作为 NSDictionary 传递,并且上面接受的答案现在已被编辑以显示这一点。
userInfo
字典作为传递对象数据的方式。
斯威夫特 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"]
}
奖金(你绝对应该这样做!):
将 Notification.Name("SomeNotificationName")
替换为 .someNotificationName
:
extension Notification.Name {
static let someNotificationName = Notification.Name("SomeNotificationName")
}
将 "key0"
和 "key1"
替换为 Notification.Key.key0
和 Notification.Key.key1
:
extension Notification {
enum Key: String {
case key0
case key1
}
}
为什么我一定要这样做?为了避免代价高昂的拼写错误,享受重命名,享受查找使用等......
'Key' is not a member type of 'Notification'
。见这里:https://ibb.co/hDQYbd2
Key
结构已被删除。我正在更新答案
斯威夫特 2 版本
正如@Johan Karlsson 指出的那样......我做错了。这是使用 NSNotificationCenter 发送和接收信息的正确方法。
首先,我们看一下 postNotificationName 的初始化器:
init(name name: String,
object object: AnyObject?,
userInfo userInfo: [NSObject : AnyObject]?)
我们将使用 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."
然后我们将字典传递给我们的对象参数。
发件人
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 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)
}
}
object
(在 NotificationCenter.default.post
调用中)传递对象 - 但是,这不是它的用途。 Apple 文档指出,object
是“发布通知的对象。”。请改用 userInfo
来传递自定义数据(如本页许多其他答案所建议的那样)。
object
参数的实际用途以及如何使用它的帖子:stackoverflow.com/questions/8779220
messageTotal
设置为 UIButton 上的徽章,您知道如何使用新的徽章计数刷新按钮吗?在viewDidLoad
中显示图像的代码是UIBarButtonItem *eRXButton = [BarButtonBadge barButtonWithImage:buttonImage badgeString:@"1" atRight:NO toTarget:self action:@selector(eRXButtonPressed)];