美文网首页
Category 和 Extension

Category 和 Extension

作者: 乔克蜀黍 | 来源:发表于2021-10-12 11:32 被阅读0次

Category VS Extension

Category
  • category只能给某个已有的类扩充方法,不能扩充成员变量
  • category中也可以添加属性,只不过@property只会生成setter和getter的声明,不会生成setter和getter的实现以及成员变量。
  • 如果category中的方法和类中原有方法同名,运行时会优先调用category中的方法。也就是,category中的方法会覆盖掉类中原有的方法。所以开发中尽量保证不要让分类中的方法和原有类中的方法名相同。避免出现这种情况的解决方案是给分类的方法名统一添加前缀。比如category_

Category加载过程

  1. 通过Runtime加载某个类的所有Category数据
  2. 把所有Category的方法、属性、协议数据,合并到一个大数组中
    后面参与编译的Category数据,会在数组的前面
  3. 将合并后的分类数据(方法、属性、协议),插入到类原来数据的前面
Extension

extension被开发者称之为扩展、延展、匿名分类。extension看起来很像一个匿名的category,但是extension和category几乎完全是两个东西。和category不同的是extension不但可以声明方法,还可以声明属性、成员变量。extension一般用于声明私有方法,私有属性,私有成员变量。

extension在编译期加载到类,它就是类的一部分,但是category则完全不一样,它是在运行期加载到类。extension在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,它、extension伴随类的产生而产生,亦随之一起消亡。

Q&A

Category的实现原理

Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息
在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)

Category和Class Extension的区别是什么?

Class Extension在编译的时候,它的数据就已经包含在类信息中,Category是在运行时,才会将数据合并到类信息中

Category中有load方法吗?load方法是什么时候调用的?load 方法能继承吗?

有load方法
load方法在runtime加载类、分类的时候调用
load方法可以继承,但是一般情况下不会主动去调用load方法,都是让系统自动调用

Category能否添加成员变量?如果可以,如何给Category添加成员变量?

默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现

添加关联对象

void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)

获取关联对象

id objc_getAssociatedObject(id object, const void * key)

移除所有关联对象

void objc_removeAssociatedObjects(id object)
  • 关联对象并不是存储在被关联对象本身内存中
  • 关联对象存储在全局的统一的一个AssociationsManager中

相关文章

网友评论

      本文标题:Category 和 Extension

      本文链接:https://www.haomeiwen.com/subject/ujudoltx.html