复制对象

来源:互联网 发布:win10电脑优化软件 编辑:程序博客网 时间:2024/05/21 19:45

复制对象

一、copymutableCopy方法

1、简介:Foundation类实现了名为copymutableCopy的方法,可以使用这些方法创建对象的副本。通过实现一个符合<NSCopying>(不可变的)协议      或<NSMutableCopying>(可变的)(用于制作副本)的方法来完成此任务。

注:产生一个对象的可变副本并不要求被复制的文件本身是可变的;这种情况同样适用于不可变副本,可以创建可变对象的不可变副本。

2、复制对象副本与使用赋值语句的区别:

赋值的结果仅仅是将对象的地址复制到另一对象中。操作结束时,两个变量都指向内存中的同一地址。而使用copymutableCopy复制对象副本的在内存中创建了一个新的副本,并复制了它的所有元素。

3、使用方法,如:

NSMutableArray *dataArray = [NSMutableArray arrayWithObjects: @”One”, @”Two”, nil];

NSMutableArray *dataArray2;

dataArray2 = [dataArray mutableCopy];

二、浅复制与深复制

1、浅复制:浅复制仅复制对象本身。

2、深复制:在浅复制的基础上,连同引用的元素对象也一起复制。

3、浅复制与深复制的区别:

1>当复制的对象中的元素为完全值类型时没有区别。

2>、当复制的对象中的元素为引用对象时;浅复制复制对象时,在内存中为新的对象分配了空间,并且将单个元素复制到新的数组中。然而将原始数组中的每个元素复制到新位置意味:仅将引用从一个对象元素复制到另一个对象元素。也就是对象中的元素都指向内存中的同一个字符串,与将一个对象赋值给另一个对象无区别。而深复制,在复制对象时为对象中的每个元素创建完全不同的副本。

4注:

1>、此情况使用浅复制不能随便删除对象中的元素,否则会造成另一对象引用元素失效。

2>、系统默认执行浅复制。

三、实现<NSCopying>协议

1、要实现使用自己的类进行复制,必须根据<NSCopying>协议实现其中一两个方法。

2interface指令应该如下所示:

@interface Fraction: NSObject <NSCopying>;

3、注意:

1>、必须考虑一个事实:超类可能已经实现了它自己的复制策略。

2>、实现<NSCopying>协议时,类必须实现copyWithZone: 方法来响应cipy消息。(这条消息仅将一条带有nil参数的copyWithZone: 消息发送给你的类)。

3>、如果你的类可以产生子类,那么cipyWithZone: 方法将被继承。

4>、如果编写一个类的copyWithZone: 方法,而该类的超类敢实现了<NSCopying>协议,那么应该先调用超类的copy方法以复制继承来的实例变量,然后加入自 己的代码以复制想要添加该类中的任何附加的实例变量。

四、用赋值方法和取值方法复制对象

1、只要实现赋值方法或取值方法,都应该考虑实例变量中存储的内容,要检索的内容以及是否需要保护这些值。

例:考虑使用setName: 方法来设置AddressCard对象的名称时:

[newCard setname: newName];

假设newName是一个字符串对象,它包含新地址卡片的名称。假定在赋值方法全程内,你中是简单地将参数赋值给相应的实例变量:

-(void) setName: (NSString *) theName

{

name = theName;

}

为了避免更改程序的newName中包含的一些字符,而无意间对程序产生影响。通过使用alloc方法来创建新的string对象,然后使用inteWithString: 函数将该方法提供的参数值赋给它,可以实现在赋值对象内产生副本。

2、还可以编写如下的setName: 方法来使用copy:

-(void) setName: (NSString *) theName

{

name = [theName copy];

}

当然,要使赋值方法全程的内存管理友好一些,首先应该自动释放旧的值,如下所示:

-(void) setName: (NSString *) theName

{

[name autorelease];

name = [theName copy];

}

3、如果在属性声明中为实例变量指定了copy属性,那么合并后的方法会使用类的copyyyif(你编写的copy方法或继承的copy方法)。所以下列property声明

@property (nonatomic, copy)  NSString *name;

会生成一个合并的方法,其行为类似于

-(void)  setName: (NSString *)theName

{

If(theName != name)

{

[name release];

Name = [theName copy];

}

}