一、协议
声明:
@protocol NSCoding(协议名称)
实现的方法...........
@end(以end结束)
采用:
@interface Car:NSObject<NSCoding>(用尖括号引起来)
{
}
@end
二、复制(Foundation框架支持复制的类,默认是浅复制)
1、深复制与浅复制
浅复制:
新复制的对象只指向现有的引用对象,对象里的属性、包含的对象不做复制,NSArray就是浅复制。如果复制一个NSArray类的对象,该对象包含五个NSString类的对象,则你最终得到的是五个可供程序使用的字符串对象,而不是十个字符串对象。即每个新对象最终获得一个指向一个字符串对象的指针。
深复制
将复制所有的引用对象,如果NSArray是深复制,即在复制操作完成以后将得到十个可用的字符串对象。
默认的iOS类并没有遵守copy相关的协议,如果想自定义一下copy 那么就必须遵守NSCopying,并且实现 copyWithZone: 方法,如果想自定义一下mutableCopy 那么就必须遵守NSMutableCopying,并且实现 mutableCopyWithZone: 方法。
对于系统的非容器类对象:即NSString,NSNumber之类的
对于一不可变对象,copy是浅复制(指针复制),mutableCopy是深复制(对象复制),对于一可变对象,都是深拷贝,但是copy返回的对象都是不可变的。(对于NSString用copy,对于NSMutableString用mutableCopy,否则会编译出错)如下:
NSString *string = @"origion";
NSString *stringCopy = [string copy];(查看内存可以发现string 和stringCopy值相同一块内存)
NSMutableString *stringMCopy = [string mutableCopy];(深复制,系统给stringMCopy重新分配了一片内存,但是内存中的内容和和string中的内容还是一样的)
对于系统的容器类对象:即NSArray,NSDictionary之类的
NSArray *array1 = [NSArray arrayWithObjects:@"a",@"b",@"c",nil];
NSArray *arrayCopy1 = [array1 copy];(浅复制(指针复制):即array1和arrayCopy1是同一个NSArray对象,包括array里面的元素也是指向相同的指针)
NSMutableArray *mArrayCopy1 = [array1 mutableCopy]; // (深复制(对象复制):mArrayCopy1是array1的可变副本,指向的对象和array1不同,但是其中的元素和array1中的元素指向的是同一个对象。mArrayCopy1还可以修改自己的对象)
但是不管是深复制还是浅复制,对于容器内的元素内容都是指针复制,所以,深复制也不是真正意义上的深复制,但是指针复制已经足够。
retain和copy的区别
retain:
NSMutableArray *array=[NSMutableArray arrayWithObjects:@"one",@"two",@"three",@"four",nil];
NSMutableArray *retainArray=[array retain];
[retainArray removeLastObject];
for(NSString *str in array)
{
NSLog(@"the part is %@",str);
}
NSLog(@"the retaincount is %ld",[retainArray retainCount]);
2014-05-19 10:58:22.639 objective[1095:303] the part is one
2014-05-19 10:58:22.641 objective[1095:303] the part is two
2014-05-19 10:58:22.641 objective[1095:303] the part is three
2014-05-19 10:58:22.641 objective[1095:303] the retaincount is 2
copy:
NSMutableArray *array=[NSMutableArray arrayWithObjects:@"one",@"two",@"three",@"four",nil];
NSMutableArray *retainArray=[array mutableCopy];
[retainArray removeLastObject];
for(NSString *str in array)
{
NSLog(@"the part is %@",str);
}
NSLog(@"the retaincount is %ld",[retainArray retainCount]);
2014-05-19 10:59:03.826 objective[1104:303] the part is one
2014-05-19 10:59:03.828 objective[1104:303] the part is two
2014-05-19 10:59:03.828 objective[1104:303] the part is three
2014-05-19 10:59:03.829 objective[1104:303] the part is four
2014-05-19 10:59:03.829 objective[1104:303] the retaincount is 1
2、举例
(1)、复制Engine
@interface Engine:NSObject<NSCopying>
@end
因为Engine类采用了NSCopying协议,所以我们必须实现copyWithZone:方法,zone是NSZone类的一个对象,只想一块可供分配的内存区域。实现如下:
-(id) copyWithZone:(NSZone *) zone
{
Engine * engine;
engine=[[[self class] allocWithZone:zone]init];//copyWithZone:方法首先得获得Self对象所属的类,然后向其所属的类发送allocWithZone:消息(因为 allocWithZone:是一个类方法,所以首先得找到其所属的类),以分配内存并创建一个该类的新对象,最后发送init消息使其初始化
return engine;
}
2、复制Tire
@interface Tire:NSObject<NSCopying>
{
float pressure;
float treadepth;
}
@end
-(id) copyWithZone:(NSZone *) zone
{
Tire * tire;
tire= [ [ [self class] allocWithZone:zone ] initWithPressure:pressure treadDepth:treadDepth];
return tire;
}
AllWeatherRadial是Tire的子类
@interface AllWeatherRadial:Tire(继承的时候相关的协议也继承,因此不必写)
{
float rainHanding;
float snowHandig;
}
@end
初始化方法
-(id) copyWithZone: (NASZone * zone)
{
AllWeatherRadial * tire;
tire=[super copyWithZone:zone];(调用父类init方法)
[tire setRainHanding: rainHanding];
[tire setSnowHanding:snowHandig];
return tire;
}