NSNotification对象方向

时间:2013-03-20 15:41:51

标签: ios objective-c nsnotifications

我正在阅读iOS Big Nerd Ranch书籍,其中一个例子展示了如何将观察者添加到NSNotificaionCenter:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(orientationChanged:)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:[UIDevice currentDevice]];

现在在orientationChanged中,从NSNotification中发布的对象中检索方向:

- (void)orientationChanged:(NSNotification *)note {
    NSLog(@"orientationChanged  %d", [[note object] orientation]);
 }

我的困惑在于这一行: [[注意对象]方向]

NSNotification的对象返回, id ,这意味着我们不知道对象的类型是编译时的UIDevice。但是,我们能够从返回的对象访问 orientation ,而不会出现编译器的错误。编译器如何知道对象类型是UIDevice并且可以接受访问方向?

2 个答案:

答案 0 :(得分:4)

  

编译器如何知道对象类型为UIDevice

没有。

它看到它是id。类型id是通用对象类型。因此,如果您发送任何消息,编译器会毫无错误地接受。即使你发送了一个不存在的。

这是因为Objective-C是一种动态语言。方法调用(消息发送),绑定,偶数类型在运行时期间由Objective-C运行时库推断。如果您向对象发送一条未实现的消息(“响应”),则抛出运行时异常而不是编译器错误。

顺便说一下,假设id的消息返回id(所以大多数指针大小的值,例如大多数整数都可以安全地返回),或者编译器查看所有的所有类上都有可用的选择器名称,并尝试将该类型与它找到的选择器之一匹配,以防它确实找到。

答案 1 :(得分:2)

Objective-C中的消息在运行时动态绑定到方法实现,而不是编译时。如果您尝试向未实现方法的对象发送消息,那么它将抛出一个无法识别的选择器发送到实例异常。

您可以通过向对象发送消息“respondsToSelector:”来询问对象是否响应选择器,从而防止抛出此异常。如果此方法返回YES,那么您可以安全地向其发送消息。这在类中实现委托时很常见,因为协议中的某些方法可能是可选的。

有关Objective-C消息传递如何工作的更多信息,您可以阅读Apple Objective-C运行时编程指南:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html#//apple_ref/doc/uid/TP40008048-CH104-SW1