分类Category 可以在不改变原来类代码的基础上,扩展类的方法
.m
需要注意的问题
1、Category可以访问原始类的实例变量,但不能添加实例变量,如果想添加变量,那就通过继承创建子类来实现。
2、Category可以重载原始类的方法,不大不推荐这么做,这样会覆盖掉原始类的方法。如果确实要重载,那就通过继承创建子类来实现。
3、和普通接口有所区别的是,在Category的实现文件中的实例方法只要你不去调用它你可以不用实现所有声明的所有方法。
4、名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法从而无法再使用初始方法。(如果同一个类的不同分类有方法重名,就看那个是最后编译的,就执行那个方法。)
分类中添加的方法,继承的子类,也会继承。
protocol 协议
定义协议格式。
使用协议的格式
// 实现协议类中定义的方法
block格式
1.直接定义
2.结合typedef 使用
.h文件格式
@interface 要扩展的类名(分类名)
扩展的方法声明。默认保护。继承的子类,可以使用。
@end
.m文件格式
@implementation Student 要扩展的类名(分类名)
扩展的方法实现。如果不想给子类使用,在.h文件中,就不要声明
@end
补充:在OC中其实,private的概念是对调用者隐藏掉方法,如果硬是调用,隐藏掉的方法(指在,m中实现,大但没有在.h中声明的方法)。也是可以运行的。不过编译器会给与警告。
.h
#import "Student.h"
// ()代表着是一个分类
// ()中的Tests是分类的名称
@interface Student (Test)
// 分类只能扩展方法,不能增加成员变量
-(void)test;
@end
.m
@implementation Student (Test)
// 分类方法的实现
-(void)test{
NSLog(@"test方法");
}
@end
需要注意的问题
1、Category可以访问原始类的实例变量,但不能添加实例变量,如果想添加变量,那就通过继承创建子类来实现。
2、Category可以重载原始类的方法,不大不推荐这么做,这样会覆盖掉原始类的方法。如果确实要重载,那就通过继承创建子类来实现。
3、和普通接口有所区别的是,在Category的实现文件中的实例方法只要你不去调用它你可以不用实现所有声明的所有方法。
4、名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法从而无法再使用初始方法。(如果同一个类的不同分类有方法重名,就看那个是最后编译的,就执行那个方法。)
分类中添加的方法,继承的子类,也会继承。
定义协议格式。
@protocol 协议名称<父协议> // 协议可以和类同名
协议中的方法。
协议中的方法,有2个属性
@required // (默认)必须实现, 但是,就算不实现,也不会报错。OC是弱语法,只会,警告
@optional // 可以实现,可以不实现
@end
使用协议的格式
// 对协议进行提前声明,跟@class的用途是一致的
@protocol 协议名;
@interface 使用协议的类名: NSObject<协议名>
使用协议方法的声明
@end
// 实现协议类中定义的方法
ButtonListener.m
#import "协议名.h"
@implementation 使用协议的类名
使用协议方法的实现
@end
block格式
1.直接定义
// 定义了一个blcok ,这个block返回int类型,接受两个int类型的参数
int (^Sum)(int,int)=^(int a,int b){
return a + b;
};
int a = Sum(10,10);
NSLog(@"%i",a);
2.结合typedef 使用
typedef int(^MySum) (int,int);
// 声明了一个blck变量
MySum sum=^(int a,int b){
return a + b;
};
// block可以访问,外部不变量,但不可以修改外部变量
int c=10;
//如果外部变量用了__block关键字,则可以修改
__block int d=10;