------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
分类(Category)
一.分类(Category)
1.Category有很多种翻译: 分类\类别\类目 (一般叫分类),也就是一些方法的声明和实现
2.作用:在不修改类的源代码的前提下,给类增加新的功能
3.使用的步骤:
此处是声明一个类
@interface Person :NSObject
@end
1)声明一个分类
格式:@interface 待扩展的类名(分类的名称)
@end
注意:类别的命名规则:类名+扩展方法,如"Person+base"。类别的接口声明与类的定义十分相似,但类别不继承父类,只需要带有一个括号,表明该类别的主要用途。
例:@interface Person (base)
-(void)eat; //吃的方法
-(void)run; //跑方法
@end
2)实现这个分类:
格式:@implementation 带扩展的类名 (分类名称)
@end
例:Person+base 类别实现
@implementation Person (base)
-(void)eat{
NSLog(@"人正在吃东西");
}
-(void)run{
NSLog(@"人在跑步");
}
@end
3.使用分类中的方法和使用类中原有的对象一样
例:Person *p=[ Person new ];
[p eat];
4.调用类别中的方法与一般成员方法调用形式完全一样,需要包含类别的头文件
5.分类的使用注意:
1).在分类的声明中不能声明实例变量,不能定义实例变量,也不能使用@property
2).在分类的方法中,可以访问类中的实例变量
3).在分类中存在和类同名的方法,优先访问的是分类的方法
4).当在多个类别中有同名的方法的时候,执行的最后编译的那个类别的同名方法
分类 > 原类
最后编译的分类 > 其他的分类
例:统计字符串中阿拉伯数字的个数
NSString+countNum.h
NSString+countNum.m
main.m
6. 非正式协议就是给NSObject类创建的类目(分类)又叫做非正式协议, 非正式协议一般不需要进行实现,一般在子类中进行方法的重写。
二. 分类的延展
1.延展类别又称为扩展(Extension ),延展是一个特殊的分类
2.特点:1).可以在延展中定义实例变量
2).不能使用implementation 类名()实现类别的方法
3.延展实现方法的私有
1).通过延展来实现方法的私有,延展的头文件独立。这种方法不能实现真正的方法私有,当在别的文件中引入延展的头文件,那么在这个文件中 定义的类的对象就可以直接调用在延展中定义所谓私有的方法
2).实现延展的方式是延展没有独立的头文件,在类的实现文件.m中声明和实现延展,这种方法可以很好的实现方法的私有,因为在OC中是不能引 入.m的文件的
3).实现方法私有的方式是在.m文件中得@implementation中直接实现在@interface中没有声明的方法,这样也可以很好的实现方法的私有
4.类别也扩展的区别
1).类别中只能添加方法,扩展中不仅可以增加方法还可以增加实例变量,只是该实例变量默认为私有的(作用范围只在自己类,而不是子类和其他的地 方)
2).类扩展中声明的方法没被实现,编译器会报错,但是类别中的方法没有实现是不会有任何警告的,这是因为类扩展是在编译阶段被添加到类中,类别 则是在运行的时候被添加到类中
3).类扩展不能像类别那样拥有独立的实现部分,类扩展所有的声明的方法必须依托对应类的实现来实现
4).定义在.m文件中的类扩展方法为私有的,定义在.h文件中的类扩展方法为公有,类扩展是在.m文件中声明私有方法的非常好的方式
block
一.block
1.block对象是一个C级别的语法和运行机制。它与标准的C函数类似,不同之处在于,它除了有可执行代码以外,它还包含了与堆、栈内存绑定的变量。因此,block对象包含着一组状态数据,这些数据在程序执行时用于对行为产生影响。
2.block定义格式:
1).有参数有返回值
返回值类型 (^变量名)(参数类型及个数) =^(行参列表){
代码块语句;
return;
};
例:int (^ block1) (int ,int)=^(int x ,int y){
return x+y;
};
2).有参无返回值
void(^变量名)(参数类型及个数) =^(行参列表){
代码块语句;
};
例:void(^block2) (int ,int )=^(int a, int b){
NSLog(@"%d",a+b);
};
3).无参无返回值
void(^变量名) ( ) =^ ( ){
代码块语句;
};
例:void(^block3) ( )=^(){
NSLog(@"xxxx");
};
4).给变量重新赋值:
例:block1=^(int x , int y){
return x*y;
};
2.利用typedef定义block类型,可以利用这种类型来定义block变量了
格式:typedef 返回值类型(^变量名) (参数类型列表);
例:给有参有返回值的block类型定义新的别名
typedef int (^NewType1) (int ,int );
NewType1 n =^(int a, int b){
return a+b;
};
3.block访问外部变量
当定义block的时候,block会把外部变量以const的方式复制一份,存放到block的所在内存堆区中,在默认情况下,在block内部中无法修改外部的变量,block内部也可以定义和block外部的同名的变量(局部变量),此时局部变量会暂时屏蔽外部变量的作用域
4.给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。
5.block作为函数的返回值
1.使用typedef定义一个新的类型
typedef int(^new Type)(int num1,int num2);
2.使用新类型作为函数的返回值
new Type test( ){
new Type n= ^ (int x, int y){
return x+y;
};
return n;
}
3.定义变量接受函数的返回值
4.调用block
new Type w =test();
NSLog(@"w=%d",w(34,76));
6.block变量用作方法的参数的时候 ,最好把参数类型列表部分加上 具体的形参名
例:void test (^int (int num1, int num2)){
}
int main( ){
test (^int (int num1, int num2){
return num1+num2;
};
}