xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出CPP文件
struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods;
const struct _method_list_t *class_methods;
const struct _protocol_list_t *protocols;
const struct _prop_list_t *properties;
};
从struct _category_t结构中可以看到分类包含6个元素
实现一个分类看看转成C++代码,下面是一个NSObject分类Test
@interface NSObject (Test)<NSCopying, NSMutableCopying>
@property (nonatomic, assign) int age;
- (void)test01;
+ (void)test02;
@end
@implementation NSObject (Test)
- (void)test01 {}
+ (void)test02 {}
- (id)copyWithZone:(nullable NSZone *)zone {return [NSObject new];}
@end
3.1 Test 分类在C++的初始化
static struct _category_t _OBJC_$_CATEGORY_NSObject_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) =
{
"NSObject",
0, // &OBJC_CLASS_$_NSObject,
(const struct _method_list_t *)&_OBJC_$_CATEGORY_INSTANCE_METHODS_NSObject_$_Test,
(const struct _method_list_t *)&_OBJC_$_CATEGORY_CLASS_METHODS_NSObject_$_Test,
(const struct _protocol_list_t *)&_OBJC_CATEGORY_PROTOCOLS_$_NSObject_$_Test,
(const struct _prop_list_t *)&_OBJC_$_PROP_LIST_NSObject_$_Test,
};
"NSObject":所属类(name)
0, // &OBJC_CLASS_$_NSObject:cls
(const struct _method_list_t *)&OBJC$CATEGORY_INSTANCE_METHODS_NSObject$_Test : 对象方法列表(instance_methods)
(const struct _method_list_t *)&OBJC$CATEGORY_CLASS_METHODS_NSObject$_Test:类方法列表(class_mehtods)
(const struct _protocol_list_t *)&OBJC_CATEGORY_PROTOCOLS$NSObject$_Test:协议列表(protocols)
(const struct _prop_list_t *)&OBJC$PROP_LIST_NSObject$_Test:属性列表(proerties)
从Test分类初始化我们知道了Category存储的内容,现在我们继续分析他们
instance_methods
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[2];
} _OBJC_$_CATEGORY_INSTANCE_METHODS_NSObject_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
2,
{{(struct objc_selector *)"test01", "v16@0:8", (void *)_I_NSObject_Test_test01},
{(struct objc_selector *)"copyWithZone:", "@24@0:8^{_NSZone=}16", (void *)_I_NSObject_Test_copyWithZone_}}
};
class_mehtods
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[1];
} _OBJC_$_CATEGORY_CLASS_METHODS_NSObject_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
1,
{{(struct objc_selector *)"test02", "v16@0:8", (void *)_C_NSObject_Test_test02}}
};
protocols
------------**NSCopying start**------------
static const char *_OBJC_PROTOCOL_METHOD_TYPES_NSCopying [] __attribute__ ((used, section ("__DATA,__objc_const"))) =
{
"@24@0:8^{_NSZone=}16"
};
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[1];
} _OBJC_PROTOCOL_INSTANCE_METHODS_NSCopying __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
1,
{{(struct objc_selector *)"copyWithZone:", "@24@0:8^{_NSZone=}16", 0}}
};
struct _protocol_t _OBJC_PROTOCOL_NSCopying __attribute__ ((used)) = {
0,
"NSCopying",
0,
(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_NSCopying,
0,
0,
0,
0,
sizeof(_protocol_t),
0,
(const char **)&_OBJC_PROTOCOL_METHOD_TYPES_NSCopying
};
struct _protocol_t *_OBJC_LABEL_PROTOCOL_$_NSCopying = &_OBJC_PROTOCOL_NSCopying;
------------**NSCopying end**------------
------------**NSMutableCopying start**------------
static const char *_OBJC_PROTOCOL_METHOD_TYPES_NSMutableCopying [] __attribute__ ((used, section ("__DATA,__objc_const"))) =
{
"@24@0:8^{_NSZone=}16"
};
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[1];
} _OBJC_PROTOCOL_INSTANCE_METHODS_NSMutableCopying __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
1,
{{(struct objc_selector *)"mutableCopyWithZone:", "@24@0:8^{_NSZone=}16", 0}}
};
struct _protocol_t _OBJC_PROTOCOL_NSMutableCopying __attribute__ ((used)) = {
0,
"NSMutableCopying",
0,
(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_NSMutableCopying,
0,
0,
0,
0,
sizeof(_protocol_t),
0,
(const char **)&_OBJC_PROTOCOL_METHOD_TYPES_NSMutableCopying
};
struct _protocol_t *_OBJC_LABEL_PROTOCOL_$_NSMutableCopying = &_OBJC_PROTOCOL_NSMutableCopying;
------------**NSMutableCopying end**------------
------------**分类中的协议 end**------------
static struct /*_protocol_list_t*/ {
long protocol_count; // Note, this is 32/64 bit
struct _protocol_t *super_protocols[2];
} _OBJC_CATEGORY_PROTOCOLS_$_NSObject_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
2,
&_OBJC_PROTOCOL_NSCopying,
&_OBJC_PROTOCOL_NSMutableCopying
};
static struct /*_prop_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count_of_properties;
struct _prop_t prop_list[2];
} _OBJC_$_PROP_LIST_NSObject_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_prop_t),
2,
{{"age","Ti,N"},
{"sex","Ti,N"}}
};
到这里我们基本知道了Category转为C++中实现,知道了他真实的类型为结构体,接下来我们看看Category在苹果源码中的声明吧
苹果源码是在不停更新的,这里看到的版本是"818.2"
struct category_t {
const char *name;
classref_t cls;
WrappedPtr<method_list_t, PtrauthStrip> instanceMethods;
WrappedPtr<method_list_t, PtrauthStrip> classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
protocol_list_t *protocolsForMeta(bool isMeta) {
if (isMeta) return nullptr;
else return protocols;
}
};
从源码的表现来看基本上和我们转为C++上一样