从OC代码转为C++代码查看Category实现

  1. 使用命令将OC代码转为CPP
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出CPP文件
  1. Category在C++中结构
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个元素

  1. 实现一个分类看看转成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,
};

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++上一样