如何在 Objective-C 上发送带有参数的通知?

Posted

技术标签:

【中文标题】如何在 Objective-C 上发送带有参数的通知?【英文标题】:How to send a notification with parameters on Objective-C? 【发布时间】:2013-04-11 19:53:50 【问题描述】:

我需要将通知@"willAnimateRotationToInterfaceOrientation" 与参数toInterfaceOrientationduration问题#1)发送给应用程序上的所有UIViewController问题#2)。怎么写代码?

[[NSNotificationCenter defaultCenter]
  addObserver:self
     selector:@selector(willAnimateRotationToInterfaceOrientation:toInterfaceOrientation:duration)
         name:@"willAnimateRotationToInterfaceOrientation"
       object:nil];

[[NSNotificationCenter defaultCenter] 
  postNotificationName:@"willAnimateRotationToInterfaceOrientation"
                object:self];

【问题讨论】:

相关问题:***.com/questions/15957077/… 【参考方案1】:

使用postNotificationName:object:userInfo: 并捆绑您希望在userInfo 字典中传递的任何参数。

例子:

您可以发布这样的通知

NSDictionary * userInfo = @ @"toOrientation" : @(toOrientation) ;
[[NSNotificationCenter defaultCenter] postNotificationName:@"willAnimateRotationToInterfaceOrientation" object:nil userInfo:userInfo];

然后通过执行以下操作检索您传递的信息:

- (void)willAnimateRotationToInterfaceOrientation:(NSNotification *)n 
    UIInterfaceOrientation toOrientation = (UIInterfaceOrientation)[n.userInfo[@"toOrientation"] intValue];
  //..

总而言之,用于处理通知的选择器采用NSNotification 类型的一个可选参数,您可以在userInfo 字典中存储您想要传递的任何信息。

【讨论】:

代码有以下错误: 1. 程序中出现意外的'@'。 2. 'UIInterfaceOrientation' 类型的集合元素(又名'enum UIInterfaceOrientation')不是Objective-C 对象。 您需要将toOrientation 括在括号之间。固定。【参考方案2】:

这并不像你想象的那样工作。通知消息调用有一个可选参数,即NSNotification 对象:

-(void)myNotificationSelector:(NSNotification*)note;
-(void)myNotificationSelector;

通知对象有一个属性userInfo,它是一个字典,可以用来传递相关信息。但是您不能注册任意选择器以供通知中心调用。您通过使用-postNotificationName:object:userInfo: 而不是-postNotificationName:object: 来传递带有通知的字典; userInfo 参数只是您创建的 NSDictionary

【讨论】:

谢谢,但是否可以向应用程序的所有(或所有可见的)UIViewControllers 发送通知? 仅当他们都注册了该通知时。请注意,如果您通过调用 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications] 来请求它,则可以使用现有的通知 UIDeviceOrientationDidChangeNotification(但您仍然必须为其注册每个视图控制器)。 当他们调用NSNotificationCenter -addObserver:selector:name:object: 时,它将被发送到所有将该指针传递给object 参数的对象。 绝对。其实你只需要在addObserver:::中传递nil即可;然后,您将收到所有通知,即使 postNotificationName:object:object 具有非 nil 值。 查看 Gabriele 的代码。您需要将两个值都推入NSNumbers,因为NSDictionary 只能保存对象值。【参考方案3】:

您使调用方法更容易,它需要更少的参数并为您执行复杂的调用。

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

- (void)doStuff 
  [self willAnimateRotationToInterfaceOrientation:someOrientation
                                    toOrientation:someOtherOrientation
                                         duration:1];


你不应该自己打电话给willAnimateRotationToInterfaceOrientation:。而是创建一个名为 form 该方法的方法,其中包含您要在轮换和其他时间激活的代码。

【讨论】:

但是如何使用userInfo传递参数?

以上是关于如何在 Objective-C 上发送带有参数的通知?的主要内容,如果未能解决你的问题,请参考以下文章

如何发送带有 HTTP HEADERS 的 PUT 请求和带有 Objective-C 的 FILE?

objective-c HTTP POST 以表单形式发送请求

给定 nil 参数时要做啥的 Objective-c 约定?

如何在 Objective-C 中将 BOOL 变量作为参数传递?

如何从Javascript调用Objective-C方法并将数据发送回iOS中的Javascript?

带有布尔参数的 Objective-C 方法中奇怪的“选择器修饰”