Category 分类 ,又称为类别、类目
概念
Category有多种翻译:分类、类别、类目(一般叫分类的多)
Category式OC特有的语法,其他语言没有的语法(类似于C#语言中的"扩展方法"和partial 关键字
作用
在不修改原有类的基础上增加新的方法
一个庞大的类可以分模式开发
一个庞大的类可以由多个人来编写,更有利于团队合作
使用Category的作用
)对现有类进行扩展
比如,你可以扩展Cocoa touch框架中的类,你在列表中增加的方法会被子类所继承,而且在运行时跟其他的方法没有区别
)作为子类的替代手段
不需要定义和使用一个子类,你可以通过Category直接向已有的类里增加方法
)对类中的方法归类
利用category把一个庞大的类划分为小块来分别进行开发,从而更好地对类中的方法进行更新和维护
使用category的步骤
声明--->实现---->使用 注意:类别的命名规则
类别+扩展方法,如"NNString+countNum"
类别的接口声明与类的定义十分相似,但类别不继承父类,只需要带有一个括号,表明该类别的主要用途
category声明
在.h文件中,声明类别: @interface ClassName(CategoryName)
NewMethod; //在类别中添加方法
//不允许在类别中添加变量
@end 说明:
声明类别格式:
)新增加的方法必须在写@interface 与 @end之间
)ClassName 现有类的类名(要为哪个类扩展方法)
)CategoryName 待声明的类别名称
)NewMethod 新增加的方法
注意:
不允许在声明类别的时候定义变量
category实现
在.m文件中(也可以在.h中实现),实现类别:
@implementation ClassName(CategoryName)
NewMethod{
......
}
@end 说明:
实现类别格式
)新方法的实现必须写在 @implementation 与@end之间
)ClassName 现有类的类名
)CategoryName 待声明的类别名称
)NewMethod 新增加的方法的实现
1.
2.
3.
也可以通过图形界面生成类别
1.
2.
3.
分类的使用注意事项
)分类只能增加方法,不能增加成员变量、@property(可能编译不报错,但是运行有问题)
)分类可以访问原来类中的成员变量
)如果分类和原来类出现同名方法,优先调用分类中的方法,原来类中的方法会被忽略
)方法调用的优先级(从高到低)
分类(最后参与编译的分类优先),只要有分类就优先调用分类,不考虑与主类的编译顺序
分类的编译顺序
最下面的最后编译
Category的非正式协议
非正式协议:
非正式协议就是给NSObject类创建的类目又叫做非正式协议,非正式协议一般不需要进行实现,一般在子类中进行方法的重写. 例如:
#import "NSObject+run.h" @implementation NSObject (run)
-(void)run{
NSLog(@"NSObject run");
}
@end 然后写个Student 继承与NSObject
这样Student就可以直接运行 run方法
Student *stu = [Student new];
[stu run]; 这就是非正式协议
Category延展
概念:
延伸类别又称为扩展(Extendsion)(也可以理解为匿名类别)
Extension是Category是一个特例
其名字为匿名(为空),并且新增加的方面一定要予以实现.(Category没有这个限制)
例如: @interface Student()
@end 实现:
通过延展来实现方法的私有,延展的头文件独立.这种方法不能实现真正的方法私有,当在别的文件中引入延展的头文件,那么在这个文件中定义的类的对象就可以直接调用在延展中定义所谓私有的方法
//对类的延展-隐藏方法 wrap的一种手段(非强制)
.h文件
@interface SceneManager()
+(void)wrap;
@end .m文件
@implementation SceneManager
+(void)wrap{
.....
}
@end 调用:
[SceneManager wrap];
//这里会报一个警告: Class method of "+wrap" not found
//不过虽然是警告,不过运行是正常的,不过这么写得自我规范上不好,即使编译器没有做强制限制,我们自己也要限制自己
//不然,延展方法就毫无意义可言 第二种实现:
延展的方式是延展没有独立的头文件,在类的实现文件.m中声明和实现延展,这种方法可以很好地实现方法的私有,因为在OC中是不能引入.m的文件的 .m文件
@interface SceneManager()
+(void)wrap;
@end
@implementation SceneManager
+(void)wrap{
......
}
@end 调用
[SceneManager wrap]; 第三种实现:
私有的方式是在.m文件中得@implementation中直接实现在@interface中没有声明的方法,这样也可以很好的实现方法的私有