Category 和 Extension

91 阅读2分钟

category 分类

主要作用是为存在的类添加方法,可以把类的实现放在不同的文件里;为已经存在的类添加方法, 使模块化,组件化(不同功能不同的分类)。可以在不修改原来类的基础上,为一个类 扩展方法。 最主要的应用:给系统自带的类扩展方法。(可以为任何类添加分类,即使没有类的源码,引入分类的头文件后,就可以在其他的类中引用分类的方法)
1)减少单个文件的体积 2)把不同的功能组织到不同的category。3)多个开发者可以同时开发一个类。4)可以按需加载需要的category

  • 本质就是一个_category_t结构体,成员有类名name,类指针,类方法,实例方法,协议,属性列表(和objc_class的成员变量有基本的相像,所以叫分类);但分类中只能访问类的.h定义的成员变量,且分类不能增加成员变量,如果分类中声明了一个属性,那么分类只会生成这个属性的set、get方法声明,也就是不会有实现;
  • 原理
    • 编译时只是个结构体,运行时会通过runtime加载分类的数据,把所有分类的类方法、实例方法、协议、属性列表合并到一个大数组,后编译的分类数据在数组的前面;所以有相同名字的方法时,调用后编译的分类的方法;
    • 合并后的分类数据大数组会添加在原来类的数据之前,所以分类与类同名方法会调用分类的;

image.png 上述代码中,可以将分类声明和实现放在单独的文件,命名为tiaoZhuanViewController+tiaoZhuanAddtion.h/m,类名+有某种功能的分类名

  • 如果要在分类中添加属性,直接添加,运行时会crash,找不到属性的getter和setter,这样可以手动添加这两个方法,但在分类中找不到属性,可以利用运行时objc_getAssociatedObjectobjc_setAssociatedObject
- (NSString *)gameName{
    return objc_getAssociatedObject(self, _cmd);
}
- (void)setGameName:(NSString *)gameName {
    objc_setAssociatedObject(self, @selector(gameName), gameName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

extension 类扩展

extension可以为类添加属性变量和实例变量,在类的.m文件中声明,声明方法如下

image.png 在.m声明的扩展内的属性、方法,其他类访问不了,一般用于封装私有方法

  • 和类一起被编译,编译后被合并到类

区别

  • category 运行时被合并到类,extension编译完被合并到类
  • category 添加方法,不可以添加属性,可以一个分类放在单独的文件里,在单独的文件里实现;extension添加属性变量、方法,添加的方法必须在类的.m中实现