category 下称类别允许你甚至在没有类源码的情况下扩展一个类的功能,给它增加方法。
** 这个可以理解为 "mixin" 的一种机制。
主要作用是使相同的方法在没有继承关的类中复用。
要使用它需要在类的@interface 文件中的category 处指名方法的名并在对应的实现文件中编写代码。
但是不能使用 category 为类添加新的实例变量。
category 只是一种编译时手段,定义在里面的方法与类的实例方法在运行时没有任何的不同。
#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end
因为 category 可能需要使用类的实例变量,因此需要import 它扩展的类的interface 文件。
#import "ClassName+CategoryName.h"
@implementation ClassName ( CategoryName )
// method definitions
@end
category 的实现文件命名如上面标识的那样。
category 与类的关系是多对一,即一个类可以有多个不同方法集的扩展,但是一个category 只能被应用于一个类(待确认)
category的几个典型的应用场景:
1。对框架提供类的扩展(没有源码,不能修改)。
2。 不想生成一个新的子类的情况下,比如对 NSArray 的扩展。
3。 方便做项目管理,可以将一份源码在多个地方共享或者做方法版本管理、多人协作开发、用本地版本替换公共版本实现。
不建议在 category 中覆盖类中的方法,因为在 category 中的方法不能调用 superClass 的方法(因为没有元数据支持)
category 方法不能覆盖于同一class 的其它 category 中的方法。因为不法预知他们的加载优先顺序,就可能在编译时出错。
对类库的 category 方法覆盖对导致整个类库的行为发生变化,因此调用那些方法的类不知道方法的实现已经发生了变化。
警告:
虽然 category 不限于任何 class ,但是仍然不建议编写针对 rootClass 的 category. 原因是影响面较大,其它开发人员如果不注意的话就会出问题。
而且类对象也可能调用这些方法,甚至在调用时的 self 指针不是实例而是类对象本身。
关于Extensions
类的Extension 可以当作是匿名的 category
那么有什么用的,就是定义在里面的方法不能被其它的 category 覆盖掉,因为找不到 reference. 用这个来实现某种意义上的 private method