直接来自 NSObject.m 的真正实现是这样的:
- (BOOL)respondsToSelector:(SEL)aSelector {
PF_HELLO("")
return class_respondsToSelector( isa, aSelector );
}
现在,我不知道为什么PF_HELLO("")
会这样,但正如你所看到的,它实际上是在 RUNTIME 中询问类“嘿,你有这个 isa [instance] 的方法,称为 aSelector 吗?”
而且,在Objective-C中,类方法也属于实例,但是优先级较低(与类方法同名的实例方法在类方法之前被调用)。
Objective-C 的动态类型的另一个方面是id
类型实际上声明如下:
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
所以你的实例对象实际上是一个类指针。这意味着您的 -respondsToSelector 消息也会转到实例类型的类。在您的情况下,这意味着 -respondsToSelector 将首先进入 objc_class。
现在在一个测试用例中,(直接从 libFoundation 出来),我的答案总结如下:
Test *tst = [Test new];
fail_unless([tst respondsToSelector:@selector(testInstanceMethod)], "-[Test respondsToSelector:] returned NO for a valid instance method (testInstanceMethod).");
fail_if([tst respondsToSelector:@selector(testClassMethod)], "-[Test respondsToSelector:] returned YES for a class method (testInstanceMethod).");
fail_unless([Test respondsToSelector:@selector(testClassMethod)], "+[Test respondsToSelector:] returned NO for a valid class method (testClassMethod).");
fail_if([Test respondsToSelector:@selector(testInstanceMethod)], "+[Test respondsToSelector:] returned YES for an instance method (testInstanceMethod).");
fail_unless([tst respondsToSelector:@selector(init)], "-[Test respondsToSelector:] returned NO for an inherited instance method (-[NSObject init].");
fail_unless([Test respondsToSelector:@selector(alloc)], "+[Test respondsToSelector:] returned NO for an inherited class method (+[NSObject alloc]).");
[tst release];