Category的实现原理
Category的底层数据结构
Category编译后,其本质是一个结构体
struct _category_t {
const char *name; // 类名(Person)
struct _class_t *cls; // 类对象指针(指向Person类对象)
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; // 属性列表
};
结论:
通过结构体可知,可以添加属性,方法,协议。不能添加成员变量;
Category添加属性
1:普通的类添加一个属性,系统会帮我们实现:创建一个成员变量_name; 生成setter、getter方法的声明;生成setter、getter方法的实现;
2:category不会创建成员变量;不会生成setter、getter方法的实现;
因此:直接添加属性,是不能使用的;
- (void)setSportEndTime:(NSDate *)sportEndTime
{
objc_setAssociatedObject(self, @selector(sportEndTime), sportEndTime, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSDate *)sportEndTime
{
return objc_getAssociatedObject(self, _cmd);
}
Category关联到对应的类
程序运行时,runtime会将category的数据合并到对应的类中;
按编译倒序将各分类中的方法,协议,属性分别整合成一个二维数组,然后讲整合后的分类信息附加到原类中;
如果多个Category中存在了重复的方法,怎么办
多个分类存在的情况下,受编译顺序的影响;
通过调整Targets -> Build Phases -> Compile Sources 中文件的顺序,可以调整编译顺序;
参考链接:
https://www.jianshu.com/p/296aeaa1bad1
https://www.jianshu.com/p/3d954fcd7259
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。