我已声明(在@interface和@end之间)并在A类的.m文件中实现了一个方法。例如:
- (void)zoneChange:(NSNotification *)note
{
NSLog(@"The system time zone has changed!");
}
在B类中,我想在系统区域发生变化时向观察者发送zoneChange
消息。
[[NSNotificationCenter defaultCenter] addObserver:anObserver
selector:@selector(zoneChange:)
name:NSSystemTimeZoneDidChangeNotification
object:nil];
上面的代码有效。当用户在Mac上更改时区时,会调用zoneChange
方法。但是,编译器给出了关于@selector的警告:未声明的选择器“zoneChange:”。令我感到困惑的是,由于zoneChange
是一种私有方法,为什么B类中的@selector会超出A类?有人可以帮我解释一下吗?
答案 0 :(得分:1)
私有方法只是:私有。它们仍然存在,它们只是对外界保密。 Objective-C没有内置任何内容来检查调用方法的位置并在运行时进行投诉;关于未声明的选择器的编译时警告正是B类无法看到您期望的方法!
答案 1 :(得分:1)
在Objective-C的世界中,当您编写[receiver zoneChange:note]
时,您实际上是向接收对象zoneChanged:
发送消息(receiver
),而不是直接进行函数调用。虽然最终有一些C函数被调用,但Objective-C消息仍然与传统的C函数有很大不同 - 我认为这就是为什么你感到困惑。
C函数是“静态的”。调用C函数的过程实际上只是跳到某个点并执行一些代码,这是在编译时确定的。但是,消息在运行时处理。 Objective-C是一种动态语言,这意味着您可以在运行时添加方法甚至类。因此,无法确定类是否在编译时实现(或响应)到一个特定的选择器。举个例子,NSManagedObject
的一些访问器在调用时在运行时添加。因此,尽管有警告,实际上您可以使用nil
向任何对象(包括performSelector
)发送任何消息,而不会出现编译错误。