NSObject上的类别也适用于Class

时间:2015-07-01 20:34:05

标签: objective-c

所以我在NSObject上有一个名为CustomCategory的类别,如下所示:

#import <Foundation/Foundation.h>

@interface NSObject (CustomCategory)

-(BOOL)doSomething;

@end

#import "NSObject+CustomCategory.h"

@implementation NSObject (CustomCategory)

-(BOOL)doSomething
{
    NSLog(@"Done");
    return NO;
}

@end

理想情况下,这将适用于这样的对象:

NSObject* object = [NSObject new];
[object doSomething];

然而,我发现它也可以这样工作,没有问题:

[NSObject doSomething];

所以我想知道,因为它是我通过类别添加的实例方法,为什么它也适用于类?

3 个答案:

答案 0 :(得分:3)

NSObject上的实例方法也是NSObject上的类方法。

这是因为Objective-C进行动态调度的方式。如果向任何对象发送消息,则在对象类中查找方法实现。如果您向类发送消息,那么您将向类对象发送常规消息。在所谓的元类中查找实现。元类由编译器自动生成。类方法只是元类的实例方法。这由编译器透明地处理。

继承也适用于元类级别。因此,类的元类继承自其超类的元类。我们有两个并行的继承层次结构。只有像NSObject这样的根类的处理方式不同。在那里,元类不能从超类的元类继承,因为没有超类。对于根类,元类继承自根类本身。

由于类的类方法是其元类的实例方法,而NSObjects元类继承自NSObject本身,NSObject上的实例方法也是NSObject上的类方法。

答案 1 :(得分:3)

对于在运行时源中寻找此实际位置的任何人的参考,它目前位于objc-runtime-new.mmmethodizeClass函数中:

... snip...

// Root classes get bonus method implementations if they don't have 
// them already. These apply before category replacements.

if (cls->isRootMetaclass()) {
    // root metaclass
    addMethod(cls, SEL_initialize, (IMP)&objc_noop_imp, "", NO);
}

... snip ...

...元类的+initialize方法将添加其实例中的所有方法实现,并将它们转换为类方法。

而且,与@Sven所说的相反,NSObject的元类实际上并不是NSObject。类在运行时始终具有单独的元类,无论它是否为root。

答案 2 :(得分:-2)

Objective C中的每个Class都是一个对象,这意味着它是NSObject的子类。