oc的类方法与实例方法的底层实现&元类到底是个什么鬼

以一份代码为例

//hello.h
@interfacehelloA : NSMutableString
- (void)instanceFunctionA;
+ (void)classFunctionA;
@end
@interfacehelloB : helloA
- (void)instanceFunctionB;
+ (void)classFunctionB;
@end
//hello.m
#import"hello.h"
@implementationhelloA
- (void)instanceFunctionA;
{}
+ (void)classFunctionA;
{}
@end
@implementationhelloB
- (void)instanceFunctionB;
{}
+ (void)classFunctionB;
{}
@end

使用命令clang -rewrite-objc hello.m之后可以得到源码,源码量很大不必都看,可以找出如下关键部分:

staticstruct_class_ro_t _OBJC_METACLASS_RO_$_helloA__attribute__((used, section ("__DATA,__objc_const"))) = {
        1,sizeof(struct_class_t),sizeof(struct_class_t),
        (unsignedint)0,
        0,
        "helloA",
        (conststruct_method_list_t *)&_OBJC_$_CLASS_METHODS_helloA,
        0,
        0,
        0,
        0,
};
staticstruct_class_ro_t _OBJC_CLASS_RO_$_helloA__attribute__((used, section ("__DATA,__objc_const"))) = {
        0,sizeof(structhelloA_IMPL),sizeof(structhelloA_IMPL),
        (unsignedint)0,
        0,
        "helloA",
        (conststruct_method_list_t         *)&_OBJC_$_INSTANCE_METHODS_helloA,
        0,
        0,
        0,
        0,
}

从上述代码中可以明显的看出helloA是结构_class_ro_t的对象,分别定义了类 OBJC_CLASS_RO$_helloA和元类OBJC_METACLASS_RO$_helloA,_class_ro_t结构如下

struct_class_ro_t {
unsignedintflags;
unsignedintinstanceStart;
unsignedintinstanceSize;
unsignedintreserved;
constunsignedchar*ivarLayout;
constchar*name;
conststruct_method_list_t *baseMethods;
conststruct_objc_protocol_list *baseProtocols;
conststruct_ivar_list_t *ivars;
constunsignedchar*weakIvarLayout;
conststruct_prop_list_t *properties;
};

其实这就是所谓的NSObject中的isaobjc_class结构,下面是objc_class的结构,看看是不是一样

structobjc_class {
Class isa  OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class                                        OBJC2_UNAVAILABLE;
constchar*name                                         OBJC2_UNAVAILABLE;
longversion                                             OBJC2_UNAVAILABLE;
longinfo                                                OBJC2_UNAVAILABLE;
longinstance_size                                       OBJC2_UNAVAILABLE;
structobjc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
structobjc_method_list **methodLists                    OBJC2_UNAVAILABLE;
structobjc_cache *cache                                 OBJC2_UNAVAILABLE;
structobjc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;

所以说类和元类都是对象,这样便可以理解了,而OBJC_METACLASS_RO$_helloA和OBJC_CLASS_RO$_helloA唯一不同的参数就是conststruct_method_list_t *baseMethods;一个是&OBJC$_CLASS_METHODS_helloA一个是&OBJC$_INSTANCE_METHODS_helloA,我们再来看这个的实现:

staticstruct/*_method_list_t*/{
unsignedintentsize;// sizeof(struct _objc_method)
unsignedintmethod_count;
struct_objc_method method_list[1];
} _OBJC_$_INSTANCE_METHODS_helloA__attribute__((used, section ("__DATA,__objc_const"))) = {
        sizeof(_objc_method),
        1,
        {{(structobjc_selector *)"instanceFunctionA","v16@0:8",         (void*)_I_helloA_instanceFunctionA}}
};
staticstruct/*_method_list_t*/{
        unsignedintentsize;// sizeof(struct _objc_method)
        unsignedintmethod_count;
        struct_objc_method method_list[1];
} _OBJC_$_CLASS_METHODS_helloA__attribute__((used, section ("__DATA,__objc_const"))) = {
        sizeof(_objc_method),
        1,
        {{(structobjc_selector *)"classFunctionA","v16@0:8", (void*)_C_helloA_classFunctionA}}
};

这正是我们定义的一个类方法和一个实例方法,由此可以得知,类方法实现与元类之中,实例方法实现与类之中。之前一度不明白为什么要存在元类这样一个东西,但在发现这可能是元类存在的主要目的。
说到runtime我们经常会看到一张图

oc的类方法与实例方法的底层实现&元类到底是个什么鬼_第1张图片
2900342-264a14f13872b8c1.jpg

这张图总是很让人迷惑,但是看了下述代码你可能会对这幅图的概念清晰起来

staticvoidOBJC_CLASS_SETUP_$_helloA(void) {
        OBJC_METACLASS_$_helloA.isa = &OBJC_METACLASS_$_NSObject;
        OBJC_METACLASS_$_helloA.superclass = &OBJC_METACLASS_$_NSMutableString;
        OBJC_METACLASS_$_helloA.cache = &_objc_empty_cache;
        OBJC_CLASS_$_helloA.isa = &OBJC_METACLASS_$_helloA;
        OBJC_CLASS_$_helloA.superclass = &OBJC_CLASS_$_NSMutableString;
        OBJC_CLASS_$_helloA.cache = &_objc_empty_cache;
}
staticvoidOBJC_CLASS_SETUP_$_helloB(void) {
        OBJC_METACLASS_$_helloB.isa = &OBJC_METACLASS_$_NSObject;
        OBJC_METACLASS_$_helloB.superclass =                 &OBJC_METACLASS_$_helloA;
        OBJC_METACLASS_$_helloB.cache = &_objc_empty_cache;
        OBJC_CLASS_$_helloB.isa = &OBJC_METACLASS_$_helloB;
        OBJC_CLASS_$_helloB.superclass = &OBJC_CLASS_$_helloA;
        OBJC_CLASS_$_helloB.cache = &_objc_empty_cache;
}

这是helloA和helloB装载方法
其中isa指元类,superclass指父类我们可以简化得到以下内容
helloB类的元类是helloB元类,helloB类的父类是helloA类
helloB元类的元类是NSObject元类,helloB元类的父类是helloA元类
helloA类的元类是helloA元类,helloA类的父类是NSMutableString类
helloA元类的元类是NSObject元类,helloA元类的父类是NSMutableString元类

你可能感兴趣的:(oc的类方法与实例方法的底层实现&元类到底是个什么鬼)