Category

# 概念

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;

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容