一: 使用继承关系开扩充一个类,有一个弊病,就是高耦合性
而 category(分类,类别) 能够帮助我们扩充一个类的功能
》1:创建: command+n ,在iOS下的Objective-C category, category on 类(在哪个类中扩展)
》2:之后在父类中需要使用扩展类中的功能时,需要引用 #import "分类.h"
》3:在扩展类中使用父类中的功能时,在对象方法中,[self 方法名]; 使用父类的属性(成员变量)时,[self setAge:10] ;
只要在原类中声明的成员变量都可以在分类中直接访问,_age =20
》4:不能够在分类中声明成员变量
》5:如果分类中定义实现了与原类中相同的方法,那么原类中的方法相当于被覆盖掉了
》6:在实际的开发中,最好不要出现方法覆盖
二:数据类型
》1:特性:
(1)作为参数传递
(2)作为函数的返回值
(3)声明成变量
作用:为了更加合理的分配内存空间
》2:OC中特有的数据类型为 对象类型NSObject, id类型 ,BooL类型,block类型,SEL类型
》3:block类型:与指向函数的指针比较像,用来封装一段代码。
block就是弥补了 指向函数的指针,不能够直接保存一个函数体(代码块),如没有参数时
原来是这样定义的
void test()
{
NSLog(@"test");
}
改用block后,可为:
void(^myBlock)()=^{
NSLog(@"test");
}
myBolok(); //调用
有参数时,原来是这样定义的
int sum(int a,int b)
{
return a+b;
}
改为block后为
int (^sumBlock)(int a,int b)=^int(int a,int b){
return a+b;
};
int result = sumBlock(10,20);
NSLog(@"result = %d",result);
当在开发中,你发现一个方法中的算法可以有多种实现,你一时还不能确定用哪种更好,你就可以把方法中其中一个参数定义为block方式,如实现两个数的加减乘除
在Calculate.h中声明函数
typedef int (^calculateBlock)(int a,int b);
-(int)calculateWithNumber1:(int)number1 andNumber2:(int)number2 andCalculate:(calculateBlock)calculate;
在Calculate.m中实现
-(int)calculateWithNumber1:(int)number1 andNumber2:(int)number2 andCalculate:(calculateBlock)calculate{
return calculate(number1,number2); //经常变化的功能,在设计当中叫做封装变化
}
接着在main.m中调用他 //如果想要改变block代码块之外的变量,就必须在变量前加入_block关键字(应用中一般不用) _block int x=0;
int (^sumBlock)(int a,int b)=^int(int a,int b){
// return a+b;
// return a-b;
// return a*b;
// return a/b;
int result = (a*b);
x=result;
return result;
};
Calculate *cal =[[Calculate alloc]init]; int sum = [cal calculateWithNumber1:10 andNumber2:20 andCalculate:sumBlock]; NSLog(@"result = %d",sum); NSLog(@"x=%d",x);
三:protocol(协议):协议根本上是一个给我们提供诸多的方法声明的文件,协议是由向上抽象思想转变而来的
》1:可以创建一个协议的文件bprotocol,在想遵循该协议的文件a.h中 #import "bprotocol.h",
@interface a :NSObject<bprotocol>
@end 这样a就遵循了bprotocol的协议
》2:谁遵循协议,谁就要实现协议中定义的方法,协议文件本身只是提供方法的声明,并不实现方法
》3:协议的条文,就是方法
》4:协议中有两个关键字,默认都是必须实现的
@required //必须实现的方法
@optional //可选实现的方法
》5:一个类可以遵循多个协议 @interface a :NSObject<bprotocol,cprotocol>
》6:协议本身也可以遵循其他协议,如NSObject ,这是一个基础协议。协议也可以同时遵循多个其他协议
》7:父类遵循了哪些协议,子类同样遵循哪些协议
》8:不需要许多的类去遵守的协议,也就是一个类特有的协议,我们可以把它直接在这个类的.h文件中直接声明出来。 @prototol dProtocol<NSObject>
》9:在协议当中不可以声明变量
》10:遵循协议的变量声明
要求你创建的对象 Person 必须遵循某个协议 PersonProtocol
Person<PersonProtocol> *p2 =[[Person alloc]init];
也可以这样写: id<PersonProtocol> obj = [[Person alloc]init];
四:SEL数据类型:用来包装方法的
使用@selector就能够把一个方法包装成SEL数据类型,如
有如下几个方法
-(void)eat;
-(void)call:(NSString *)number;
-(NSString *)Name;
调用时:
Person *p = [[Person alloc]init];
//[p eat]; 消息机制,这个调用eat方法也可以用以下的来实现,无参数无返回值
SEL s1 = @selector(eat);
[p performSelector:s1] //这两句也可以合成一句[p performSelector:@selector(eat)];
//有参数的情况
SEL s2 = @selector(call:);
[p performSelector:s2 withObject:@"180678990"];
//有返回值的情况
SEL s3 = @selector(Name);
NSString *str=[p performSelector:s3];
NSLog(@"%@",str);