Category In Objective-C
创始人
2025-05-29 19:16:08
0

Category In Objective-C

来源

Objective-C 2.0中新增的语言特性

可以用来做什么 ?

  1. 扩展已有的类 (仅限于为已有类增加方法) ;

  2. 分割类实现 ;

    官方原文: Distribute the implementation of your own classes into separate source files—for example, you could group the methods of a large class into several categories and put each category in a different file.

    几个显而易见的好处 :
    a. 可以减少单个文件的体积 ;
    b. 可以把不同的功能组织到不同的category里 ;
    c. 可以由多个开发者共同完成一个类 ;
    d. 可以按需加载想要的category ;

  3. 声明私有方法 ; (虽然是apple推荐, 但我并没有理解这么做有什么卵用) ;

    /** 官方示例代码, MyClass.m file*/ 
    #import "MyClass.h"@interface MyClass (PrivateMethods)
    // private method declarations
    @end@implementation MyClass
    // private method definitions
    @end
    
  4. 模拟多继承 ;

  5. 把framework的私有方法公开 ;

Category的本质是什么 ?

所有的Objective-C的类和对象,在 runtime 层都是用 struct 表示的,category 也不例外, 在 objc-class.h 中, 找到如下定义 :

/* *	Category Template*/
typedef struct objc_category *Category;struct objc_category {char *category_name;char *class_name;struct objc_method_list *instance_methods;struct objc_method_list *class_methods;struct objc_protocol_list *protocols;
};

Category 的定义中, 不难窥测, 其可为与不可也 ~ (可以增加 instance_methods, class_methods, protocols, 不可增加 instance, 故若在 Category 中新增 Property, 本质只会保留方法声明)

Category的实现分析

1. 生成测试代码

/** SQIClass.h 文件*/#import @interface SQIClass : NSObject- (void)sqiFunc;@end@interface SQIClass(SQIAddition)@property(nonatomic, copy) NSString *sqiProperty;- (void)sqiFunc;@end
/** SQIClass.m 文件*/#import "SQIClass.h"@implementation SQIClass- (void)sqiFunc
{NSLog(@"%@",@"I'm SQIClass func");
}@end@implementation SQIClass(SQIAddition)- (void)sqiFunc
{NSLog(@"%@",@"I'm SQIAddition func");
}@end

确定分析工具

$ clang -rewrite-objc SQIClass.m

clang -rewrite-objc 的作用是把oc代码转写成c/c++代码,这里选用它来窥探 OC Category 的底层实现.

具体分析 (SQIClass.cpp文件的源码分析)

以上命令会在当前目录生成大小为 3.8MB 的文件 (SQIClass.cpp), 代码共 65475 行 🤣🤮

生成文件及相关源码下载地址

Category 的 C++ 定义

// 起始于 65354 行
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 objc_category 基本一一对应, 多出来的 properties 暂时忽略.

Category增加的实例方法列表

// 起始于 65431 行
static struct /*_method_list_t*/ {unsigned int entsize;  // sizeof(struct _objc_method)unsigned int method_count;struct _objc_method method_list[1];
} _OBJC_$_CATEGORY_INSTANCE_METHODS_SQIClass_$_SQIAddition __attribute__ ((used, section ("__DATA,__objc_const"))) = {sizeof(_objc_method),1,{{(struct objc_selector *)"sqiFunc", "v16@0:8", (void *)_I_SQIClass_SQIAddition_sqiFunc}}
};

实例方法列表为: _OBJC_$_CATEGORY_INSTANCE_METHODS_SQIClass_$_SQIAddition, method_count 值为 1, 说明共有 1 个方法.

Category增加的属性列表

// 起始于 65441 行
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_SQIClass_$_SQIAddition __attribute__ ((used, section ("__DATA,__objc_const"))) = {sizeof(_prop_t),1,{{"sqiProperty","T@\"NSString\",C,N"}}
};

属性列表为: _OBJC_$_PROP_LIST_SQIClass_$_SQIAddition, count_of_properties 的值为 1, 说明共有 1 个属性.

创建分类实体, 并用上面的列表对象初始化

static struct _category_t _OBJC_$_CATEGORY_SQIClass_$_SQIAddition __attribute__ ((used, section ("__DATA,__objc_const"))) = 
{"SQIClass",0, // &OBJC_CLASS_$_SQIClass,(const struct _method_list_t *)&_OBJC_$_CATEGORY_INSTANCE_METHODS_SQIClass_$_SQIAddition,0,0,(const struct _prop_list_t *)&_OBJC_$_PROP_LIST_SQIClass_$_SQIAddition,
};

在DATA段下的objc_catlist section里保存了一个大小为1的_category_t的数组

// start line: 65472
static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [1] __attribute__((used, section ("__DATA, __objc_catlist,regular,no_dead_strip")))= {&_OBJC_$_CATEGORY_SQIClass_$_SQIAddition,
};

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...