您的位置:首页 > 移动开发 > Objective-C

[学习笔记—Objective-C]《Objective-C 程序设计 第6版》第十八章 复制对象

2015-07-10 22:21 465 查看
origin = pt;


将对象
pt
的地址复制到
origin
中。两个变量都指向内存中同一个地址

Foundation对象:将一个变量赋值给另一个对象仅仅创建了另一个对这个对象的引用(地址)。

Part 1.copy 和 mutablecopy 方法:创建对象的副本

复制对象(的引用)

dataArray2 = dataArray;//创建了内存中同一数组对象的另一个引用:总共一个数组


创建对象的副本

dataArray2 = [dataArray mutalbeCopy];//创建信的dataArray副本并复制了所有元素:总共两个数组


注意:可以创建可变对象的不可变副本。也可以创建不可变对象的可变副本。

Part 2. 浅复制与深复制

Part 2.1 浅复制

NSMutableArray *dataArray = [NSMutableArray arrayWithObjects:

[NSMutableString stringWithString:@"one"],
[NSMutableString stringWithString:@"two"],
[NSMutableString stringWithString:@"three"],nil];

NSMutableArray *dataArray2;
NSMutableString *mStr;

dataArray2 = [dataArray mutableCopy];
//两个数组(dataArray,dataArray2)的元素都指向内存中同一个字符串,等同于一个对象赋值给另一个对象,属于浅复制

mStr = dataArray[0];
//检索dataArray第一个元素 dataArray[0]返回的对象和dataArray中的一个元素指向内存中的同一个对象。

[mstr appendString:@"ONE"];
//改变mstr的同时改变了dataArray的第一个元素。由于浅复制,dataArray2也发生了改变,因为浅复制只是复制了对象的引用,内容被更改即被更改。


Part 2.2 深复制

创建数组中每个对象内容的副本,而不仅仅是这些对象引用的副本。

更改dataArray2中的第一个元素,而不改变dataArray的第一个元素:

mStr = [NSMutableString stringWithString: dataArray2[0]];
//创建一个新字符串,并存储到dataArray2的第一个位置。

[mStr appendString @"ONE"];
[dataArray2 replaceObjectAtIndex: 0 withObject: mStr];
//更改mStr并添加得到数组中


Part 3. 实现 < NSCopying > 协议

若要对自己的类进行复制,必须根据协议实现其中的方法。

协议:实现copyWithZone:方法来响应copy消息,返回不可变副本

协议:实现mutableCopyWithZone:方法,返回可变副本

在Fraction类创建新的分数

@interface Fraction: NSObject <NSCopying>

-(id) copyWithZone: (NSZone *)zone
{
Fraction *newFact = [[Fraction allocWithZone: zone] init];

[newFact setTo: numerator over: denominator];

return newFact;
}


Fraction *f1 = [[Fraction alloc]init];
Fraction *f2;

[f1 setTo: 2 over 5];

f2 = [f1 copy]; //产生f1的副本,产生新的Fraction,将f1复制其中

[f2 setTo: 1 over: 3];

[f1 print]; // 2/5 复制的操作对f1没有影响
[f2 print]; // 1/3


注意

如果将copy语句改成 f2 = f1,则改变f2的同时会改变f1。

如果产生此类的子类,copyWithZone:方法将被继承:

Fraction *newFact = [[Fraction allocWithZone: zone] init];
应该改为:
id newFract = [[self class allocWithZone: zone] init];


Part 4. 用设值方法和取值方法复制对象

赋值:

newCard.name = newName; //设置对象(AddressCard)的名称(姓名)


设值方法:

-(void) setName: (NSString *) theName
{
name = theName; //简单将参数赋值给了相应的实例变量
}


如果修改了newName的字符

为了避免改变其他对象的值,比较安全的做法是在设值方法中将对象复制一份。

使用copy版本的setName方法:

-(void) setName: (NSString *) theName
{
name = [theName copy];
}


属性的copy特性:

@property (nonatomic,copy) NSString *name;


synthesize
一同使用等效于:

-(void) setName: (NSString *) theName
{
if (theName != name)
name = [theName copy];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: