协议 深复制与浅复制

一、协议

声明:

@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];(浅复制(指针复制):即array1arrayCopy1是同一个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;

}


















你可能感兴趣的:(OS,深复制与浅复制)