编译器中的类、元类、根源类

发布时间 2023-06-10 04:50:39作者: 吴建明wujianming

编译器中的类、元类、根源类
1. 源码
main.m

#import <Foundation/Foundation.h>

@interface YCFather : NSObject

@property (nonatomic, copy) NSString *name;

+ (void)clsSayHello1;

- (void)insSayHello1;

@end

@implementation YCFather

+ (void)clsSayHello1 {}

- (void)insSayHello1 {}

@end

@interface YCSon : YCFather

@property (nonatomic, copy) NSString *midName;

+ (void)clsSayHello2;

- (void)insSayHello2;

@end

@implementation YCSon

+ (void)clsSayHello2 {}

- (void)insSayHello2 {}

@end

int main(int argc, char * argv[]) {

return 0;

}
编译器中的类、元类、根源类
1. 源码
main.m
#import <Foundation/Foundation.h>

@interface YCFather : NSObject
@property (nonatomic, copy) NSString *name;
+ (void)clsSayHello1;
- (void)insSayHello1;
@end
@implementation YCFather
+ (void)clsSayHello1 {}
- (void)insSayHello1 {}
@end

@interface YCSon : YCFather
@property (nonatomic, copy) NSString *midName;
+ (void)clsSayHello2;
- (void)insSayHello2;
@end
@implementation YCSon
+ (void)clsSayHello2 {}
- (void)insSayHello2 {}
@end

int main(int argc, char * argv[]) {
return 0;
}
2. Clang -rewrite-objc
执行下面的代码,会输出一个 main.cpp 文件。
xcrun -sdk iphoneos clang -arch arm64 -w -rewrite-objc -fobjc-arc -mios-version-min=8.0.0 -fobjc-runtime=ios-8.0.0 main.m
注意:此处使用 clang -rewrite-objc 得到的c++代码只能做参考,与真实的代码还是会有一定出入,但逻辑基本一致。
1)类的基本结构
搜索 NSObject
#ifndef _REWRITER_typedef_NSObject
#define _REWRITER_typedef_NSObject
typedef struct objc_object NSObject;
typedef struct {} _objc_exc_NSObject;
#endif
struct NSObject_IMPL {
__unsafe_unretained Class isa;
};
可以看到 NSObject 主要成员变量就是 Class ISA,下面再看看 YCFather 和 YCSon。
#ifndef _REWRITER_typedef_YCFather
#define _REWRITER_typedef_YCFather
typedef struct objc_object YCFather;
typedef struct {} _objc_exc_YCFather;
#endif
extern "C" unsigned long OBJC_IVAR_$_YCFather$_name;
struct YCFather_IMPL {
struct NSObject_IMPL NSObject_IVARS; // 继承 NSObject_IMPL 的成员变量 isa
NSString *__strong _name; // 追加自己的 _name 成员变量
};
// @property (nonatomic, copy) NSString *name;
// + (void)clsSayHello1;
// - (void)insSayHello1;
/* @end */
// @implementation YCFather
// clsSayHello1 IMP
static void _C_YCFather_clsSayHello1(Class self, SEL _cmd) {}
// insSayHello1 IMP
static void _I_YCFather_insSayHello1(YCFather * self, SEL _cmd) {}
// name 属性的 get 方法
static NSString * _I_YCFather_name(YCFather * self, SEL _cmd) { return (*(NSString *__strong *)((char *)self + OBJC_IVAR_$_YCFather$_name)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);
// name 属性的 set 方法
static void _I_YCFather_setName_(YCFather * self, SEL _cmd, NSString *name) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct YCFather, _name), (id)name, 0, 1); }
// @end
#ifndef _REWRITER_typedef_YCSon
#define _REWRITER_typedef_YCSon
typedef struct objc_object YCSon;
typedef struct {} _objc_exc_YCSon;
#endif
extern "C" unsigned long OBJC_IVAR_$_YCSon$_midName;
struct YCSon_IMPL {
struct YCFather_IMPL YCFather_IVARS; // 继承 YCFather_IMPL 的成员变量 isa 和 _name
NSString *__strong _midName; // 追加自己的 _midName 成员变量
};
// @property (nonatomic, copy) NSString *midName;
// + (void)clsSayHello2;
// - (void)insSayHello2;
/* @end */
// @implementation YCSon
// clsSayHello2 IMP
static void _C_YCSon_clsSayHello2(Class self, SEL _cmd) {}
// insSayHello2 IMP
static void _I_YCSon_insSayHello2(YCSon * self, SEL _cmd) {}
// midName 属性的 get 方法
static NSString * _I_YCSon_midName(YCSon * self, SEL _cmd) { return (*(NSString *__strong *)((char *)self + OBJC_IVAR_$_YCSon$_midName)); }
// midName 属性的 set 方法
static void _I_YCSon_setMidName_(YCSon * self, SEL _cmd, NSString *midName) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct YCSon, _midName), (id)midName, 0, 1); }
// @end
2. 类中的信息
YCFather 和 YCSon 的分析类似,这里以 YCFather 为例进行分析。成员变量列表 OBJC$_INSTANCE_VARIABLES_YCFather。
static struct /*_ivar_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count;
struct _ivar_t ivar_list[1];
} _OBJC_$_INSTANCE_VARIABLES_YCFather __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_ivar_t),
// 只有一个成员变量
{{(unsigned long int *)&OBJC_IVAR_$_YCFather$_name, "_name", "@\"NSString\"", 3, 8}} // 成员变量_name
};
实例方法列表 OBJC$_INSTANCE_METHODS_YCFather
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[5];
} _OBJC_$_INSTANCE_METHODS_YCFather __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
5, // 有5个实例方法,SEL、Encode、IMP
{{(struct objc_selector *)"insSayHello1", "v16@0:8", (void *)_I_YCFather_insSayHello1},
{(struct objc_selector *)"name", "@16@0:8", (void *)_I_YCFather_name},
{(struct objc_selector *)"setName:", "v24@0:8@16", (void *)_I_YCFather_setName_},
{(struct objc_selector *)"name", "@16@0:8", (void *)_I_YCFather_name},
{(struct objc_selector *)"setName:", "v24@0:8@16", (void *)_I_YCFather_setName_}}
};
类方法列表 OBJC$_CLASS_METHODS_YCFather。
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[1];
} _OBJC_$_CLASS_METHODS_YCFather __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
1, // 有1个类方法,SEL、Encode、IMP
{{(struct objc_selector *)"clsSayHello1", "v16@0:8", (void *)_C_YCFather_clsSayHello1}}
};
属性方法列表 OBJC$_PROP_LIST_YCFather。
static struct /*_prop_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count_of_properties;
struct _prop_t prop_list[1];
} _OBJC_$_PROP_LIST_YCFather __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_prop_t),
1, // 有1个属性
{{"name","T@\"NSString\",C,N,V_name"}}
};
元类对象 RO 的初始化 OBJCMETACLASS_RO_$_YCFather。
常见重点1:类方法存储在元类 (注意static,这些信息只存在一份)。
static struct _class_ro_t _OBJC_METACLASS_RO_$_YCFather __attribute__ ((used, section ("__DATA,__objc_const"))) = {
1, sizeof(struct _class_t), sizeof(struct _class_t),
0,
"YCFather",
(const struct _method_list_t *)&_OBJC_$_CLASS_METHODS_YCFather, // YCFather 的类方法存储在元类
0,
0,
0,
0,
};
类对象 RO 的初始化 OBJCCLASS_RO_$_YCFather。
常见重点2:实例方法存储在类 (注意static,这些信息只存在一份)
static struct _class_ro_t _OBJC_CLASS_RO_$_YCFather __attribute__ ((used, section ("__DATA,__objc_const"))) = {
0, __OFFSETOFIVAR__(struct YCFather, _name), sizeof(struct YCFather_IMPL),
0,
"YCFather",
(const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_YCFather, // 方法列表
0,
(const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_YCFather, // 成员变量列表
0,
(const struct _prop_list_t *)&_OBJC_$_PROP_LIST_YCFather, // 属性列表
};
元类 OBJC_METACLASS__YCFather∗∗、类∗∗OBJC_CLASS__YCFather**、类 **OBJC_CLASS__YCFather∗∗、类∗∗OBJC_CLASS__YCFather 的初始化。
extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;
// 元类的初始化
extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_YCFather __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_NSObject,
0, // &OBJC_METACLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_METACLASS_RO_$_YCFather,
};
extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
// 类的初始化
extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_YCFather __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_YCFather,
0, // &OBJC_CLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_CLASS_RO_$_YCFather,
};
3. 元类与类的关系绑定
常见重点3:类、元类、根源类的关系
static void OBJC_CLASS_SETUP_$_YCFather(void ) {
OBJC_METACLASS_$_YCFather.isa = &OBJC_METACLASS_$_NSObject; // YCFather元类的 isa 为 NSObject元类(根元类)
OBJC_METACLASS_$_YCFather.superclass = &OBJC_METACLASS_$_NSObject; // YCFather元类的 superclass 为 NSObject元类
OBJC_METACLASS_$_YCFather.cache = &_objc_empty_cache;
OBJC_CLASS_$_YCFather.isa = &OBJC_METACLASS_$_YCFather; // YCFather类的 isa 为 YCFather元类
OBJC_CLASS_$_YCFather.superclass = &OBJC_CLASS_$_NSObject; // YCFather类的 superclass 为 NSObject类
OBJC_CLASS_$_YCFather.cache = &_objc_empty_cache;
}
// 这里特意补上 YCSon 的关系绑定
static void OBJC_CLASS_SETUP_$_YCSon(void ) {
OBJC_METACLASS_$_YCSon.isa = &OBJC_METACLASS_$_NSObject; // YCSon元类的 isa 为 NSObject元类(根元类)
OBJC_METACLASS_$_YCSon.superclass = &OBJC_METACLASS_$_YCFather; // YCSon元类的 superclass 为 YCSon元类的
OBJC_METACLASS_$_YCSon.cache = &_objc_empty_cache;
OBJC_CLASS_$_YCSon.isa = &OBJC_METACLASS_$_YCSon; // YCSon类的 isa 为 YCSon元类
OBJC_CLASS_$_YCSon.superclass = &OBJC_CLASS_$_YCFather; // YCSon类的 superclass 为 YCFather类
OBJC_CLASS_$_YCSon.cache = &_objc_empty_cache;
}
这里比较可惜的是,无法直观地看到 OBJC_METACLASS_$_NSObject 中的结构,但可以通过运行时或源码分析,已经得到了下面这张经典的图片了。根据上面的代码分析,也可以直观的验证如图5.20所示的大部分关系。

 图1 类、元类、根源类的关系图

 

参考文献链接

https://mp.weixin.qq.com/s/r2O4gCDMY44YGmWYMMfFjQ
https://juejin.cn/post/6874391520334577677#heading-8