类别(category)
类别是oc独有的。其它语言都没有。
类别是类的一部分,类别是类的分着写的,但是编译的时候会合在一起。
概念,提供一种类为某个类添加方法而又不必编写子类的途径。
是objc语言中的扩展机制之一。
使用类别的目的。
将类实现部分部分离到不同的文件,提高程序可读性。
类别分解大的代码。
1分解大的代码 。
每个类别实现类似功能的方法。
2 ,给已有的类添加新方法,
不修改原有类的情况下,可以给类添加新方法,
注意:类别会替代原有类中同名的方法。
类别的局限
无法向类别中添加新的实例变量,类别没有位置容纳实例变量,只能添加方法。
名称冲突
类别中的方法如与原来类中已有的方法重名,将取代原有类中的同名方法,从而无法再使用原有方法。
解决名称冲突
可以在自己的类别方法名字前增加一个前缀,以确保不发生冲名称冲突。
使用类别步骤
声明,实现 实例化(使用)
协议(protocol)
协议;相当于java的接口。只提供方法,由采用协议的类去实现。
常用于两个类或模块之间进行交换数据。
非正式协议(一般不用),
正式协议
所有实现正式协议的类,必须实现该正式协议中的所有方法。
协议只有一个.h文件,只声明方法,不实现。
步骤:声明采用 实现 使用。
实现协议与普通类中方法实现形式一样
在类声明的.h文件中,要包含协议的头文件,<>加上协议名,表示采用协议。
@optional关键字
该指令后的方法都是可选的,即不一定要实现它,非正式协议完全可以替代了。
@required
是默认的,该指令后面的方法,必须要实现。
协议与数据类型。
id类型的对象可以加协议限制。
表示该对象必须遵守指定的协议。
protocol应用——复制。
浅层复制(Shallow Copy)也叫浅拷贝,该操作不会复制对象。浅拷贝后,新对象,只是指向原有对象的一个引用。例如,a如果被浅层复制给b,则b只是一个同样引用a地址的指向。
NSArray类的copy方法是浅层复制,当复制一个NSArray类的对象时,实际上复制后的对象,只是复制了原对象的一个指针,而没有复制对象本身,也就是说这个新复制的对象是原对象,指向同一个内存区域,只是同一个内容的不同名称,若其中一个对象改变了内容,那么,实际上另外一个对象的内容也改变了。
为了好理解引用c语言的方法去理解oc中的浅拷贝。
int *p;
p=(int *) malloc(4);
int *p1;
p1=p;
free(p)
oc 中的浅拷贝:
例1,Time *time=[Time new];
Time *time1=time; 这是浅拷贝。
[time relse];
例2.A*a=[A new]
A*b=a;
a 被浅拷贝给b。
那么b和一个同样引用a地址的指向。
[a release];
b指向的空间已经被释放,成为野指针,程序出错。
深层复制—— 深层复制(Deep Copy)也叫深拷贝,是一种会重新分配内存地址的拷贝方式。利用深拷贝,将会复制 产生一个新的对象,使用深拷贝后,对象a和b内容一样,但指针地址不一样,改变b并不影响a。
为了好理解引用c语言的方法去理解oc中的深拷贝。
int *p;
p=(int *) malloc(4);
*p=10;
int *p1=(int*)malloc(4);
*p=*p1;
free(p);
Time *time=[Time new];
Time *time1;
time1=[time copy];
[time release];
深拷贝
是一种会重新分配内存地址的拷贝方式。
利用深拷贝,将会复制产生一个新的对象。
建议使用深拷贝,少用浅拷贝。
A*a=[A new];
A *b=[a copy];
a 如果深复制给b。
对象a和b一样,但指针地址不一样。
a和b的值改变,都不会影响。
若自定义类要使用copy方法,必须实现NSCopying协议中的copyWithZone方法。
自定义类实现深层拷贝步骤。
采用NSCopying协议
实现NSCopying协议
调用copy方法,实现深层复制。
例:
#import <Foundation/Foundation.h>
//要想使用 copy 必须采用<NSCopying> 协议
@interface Subject : NSObject <NSCopying>
{
//课程名称
NSString *name;// NSString 是 oc 提供的字符串。
int score;//成绩。
}
@property (copy)NSString *name;
@property int score;
-(void)print;
@end
#import "Subject.h"
@implementation Subject
@synthesize name;
@synthesize score;
//实现协议
-(id)copyWithZone:(NSZone *)zone//这个函数是协议里面的方法。
{
Subject *psubject=[[Subject allocWithZone:zone]init];//初始化方法用的也是协议里面的方法。
psubject.name=name;
psubject.score=score;
return psubject;
}
-(void)print
{
NSLog(@"%@ %d",name,score);
}
@end
#import <Foundation/Foundation.h>
#import "Subject.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Subject *s1=[Subject new];
Subject *s2;
s1.name=@"Objective-c";
s1.score=99;
//将s1复制给s2.调用的是 -(id)copyWithZone:(NSZone *)zone 方法。
s2=[s1 copy];
[s1 print];
[s2 print];
[s1 release];
[s2 release];
}
return 0;
}