# 概念
category的主要作用是为已经存在的类添加方法。
Objective-C 中的 Category 就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法。
## 使用场景
1.给现有的类添加方法
2.将一个类的实现拆分成多个独立的源文件;
好处:
a)可以减少单个文件的体积
b)可以把不同的功能组织到不同的category里
c)可以由多个开发者共同完成一个类
d)可以按需加载想要的category 等等。
3.声明私有的方法。
## 实现原理
1.我们不主动引入 Category 的头文件,Category 中的方法都会被添加进主类中。我们可以通过 - performSelector: 等方式 对 Category 中的相应方法进行调用
a)将 Category 和它的主类(或元类)注册到哈希表中;
b)如果主类(或元类)已实现,那么重建它的方法列表。
2.在这里分了两种情况进行处理:Category 中的实例方法和属性被整合到主类中;而类方法则被整合到元类中(关于对象、类和元类的更多细节,可以参考我前面的博文《Objective-C对象模型》)。另外,对协议的处理比较特殊,Category 中的协议被同时整合到了主类和元类中。
3.注意到,不管是哪种情况,最终都是通过调用staticvoid remethodizeClass(Class cls) 函数来重新整理类的数据的。
## category结构体
1.所有的OC类和对象,在runtime层都是用struct表示的,category也不例外,在runtime层,category用结构体category_t.
2.category结构体的定义:
structcategory_t {
constchar*name;//类的名字(name)
classref_t cls;//类(cls)
struct method_list_t *instanceMethods; //category中所有给类添加的实例方法的列表(instanceMethods)
structmethod_list_t *classMethods;//category中所有添加的类方法的列表(classMethods)
structprotocol_list_t *protocols; //category实现的所有协议的列表(protocols)
structproperty_list_t *instanceProperties;//category中添加的所有属性(instanceProperties)
};
3.从category的定义也可以看出category可以添加实例方法,类方法;可以遵守协议,添加属性;但无法添加实例变量。
## 解决同一方法高频率调用的效率问题
Runtime源码中的IMP作为函数指针,指向方法的实现。通过它,我们可以绕开发送消息的过程来提高函数调用的效率。当我们需要持续大量重复调用某个方法的时候,会十分有用,具体代码示例如下:
void (*setter)(id, SEL, BOOL);
int i;
setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];
for ( i = 0 ; i < 1000 ; i++ )
setter(targetList[i], @selector(setFilled:), YES);
## 解决方法无响应崩溃问题
执行OC方法其实就是一个发送消息的过程,若方法未实现,我们可以利用方法动态解析与消息转发来避免程序崩溃
消息接收者重定向
//重定向类方法的消息接收者,返回一个类
-(id)forwardingTargetForSelector:(SEL)aSelector
//重定向实例方法的消息接受者,返回一个实例对象
-(id)forwardingTargetForSelector:(SEL)aSelector
消息重定向
-(void)forwardInvocation:(NSInvocation *)anInvocation;
-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector;