Category 底层原理

一个分类对应一个结构体指针对象,包含了分类中的一些信息

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 _property_list_t *protocols;       // 分类中的协议列表
    const struct _prop_list_t *properties;          // 分类中的属性列表
    ...
}

程序在编译的时候就会创建分类对应的结构体指针变量,将信息存放在变量中,
但是只有在运行时才会将分类中的对象方法,类方法等合并到类对象,元类对象中

Category的加载处理过程

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

类扩展(Extension)和协议的区别:

  • 分类是在运行时把分类信息合并到类信息中,而扩展是在编译时把信息合并到类信息中
  • 分类声明的属性,只会生成getter/setter方法,不会自动生成成员变量和方法的实现,而扩展会
  • 分类不可以添加实例变量,而扩展可以
  • 分类可以为类添加方法的实现,而扩展只能声明,不能实现

分类的局限性

  • 无法为类添加实例变量,但可以通过关联对象实现
  • 分类中的方法若和类中原本的方法重名,会覆盖元类的方法,注:并不是真正的覆盖,只是runtime在查找方法的时候因为分类排在前面,所以会先找到,后面的不在查找
  • 多个分类方法重名,会调用最后编译的那个分类中的方法

你可能感兴趣的:(Category 底层原理)