object-c 复制 (copy)

来源:互联网 发布:成都网络作家吸毒 编辑:程序博客网 时间:2024/05/17 00:16

深拷贝,和前拷贝,是一项非常重要的知识点。


浅拷贝:

尤其,实际应用中,用来拷贝对象时。
默认的,对象、对象数组用的是浅拷贝。
我们从一段代码开始吧!
需要参照的实体类:

 

NSString *aName=[[NSString alloc] initWithString:@"Tom"];

    NSString *aEmail=[[NSStringalloc]initWithString:@"Tom@yahoo.cn"];

    int aSalary=1000;

    

    NSString *bName=[[NSStringalloc]initWithString:@"LiLei"];

    NSString *bEmail=[[NSStringalloc]initWithString:@"LiLei@yahoo.cn"];

    int bSalary=1500;


   AddressCard *card1=[[AddressCard alloc]init];

   AddressCard *card2=[[AddressCard alloc]init];

    

    

    [card1 setName:aName andEmail:aEmail andSalary:aSalary];

    [card2 setName:bName andEmail:bEmail andSalary:bSalary];

    

    

   NSMutableArray *objArray=[NSMutableArray arrayWithObjects:

                          card1,

                          card2,

                         nil];

    

    

    AddressCard *tempCard=[objArrayobjectAtIndex:0];

    

    NSMutableArray *objArray2;

    objArray2=[objArraymutableCopy];

    

    

   // 输出objArray

   NSLog(@"objArray:     ");

    for (AddressCard *theCardin objArray) {

       [theCard print];

    }

    

 

2012-12-07 23:06:37.708 DemoVideo[699:1b803] objArray:     

2012-12-07 23:06:37.709 DemoVideo[699:1b803]=====================

2012-12-07 23:06:37.709 DemoVideo[699:1b803] name=Tom

2012-12-07 23:06:37.709 DemoVideo[699:1b803]email=Tom@yahoo.cn

2012-12-07 23:06:37.709 DemoVideo[699:1b803]=====================

2012-12-07 23:06:37.710 DemoVideo[699:1b803]=====================

2012-12-07 23:06:37.710 DemoVideo[699:1b803] name=LiLei

2012-12-07 23:06:37.710 DemoVideo[699:1b803]email=LiLei@yahoo.cn

2012-12-07 23:06:37.711 DemoVideo[699:1b803]=====================


    [tempCard print];


 

2012-12-07 23:07:13.025 DemoVideo[699:1b803]=====================

2012-12-07 23:07:13.027 DemoVideo[699:1b803] name=Tom

2012-12-07 23:07:13.027 DemoVideo[699:1b803]email=Tom@yahoo.cn

2012-12-07 23:07:13.027 DemoVideo[699:1b803]=====================

    

   // 输出objArray2

   NSLog(@"objArray2:     ");

    for (AddressCard *theCardin objArray2) {

       [theCard print];

    }

    

 

2012-12-07 23:07:36.547 DemoVideo[699:1b803] objArray2:     

2012-12-07 23:07:36.547 DemoVideo[699:1b803]=====================

2012-12-07 23:07:36.547 DemoVideo[699:1b803] name=Tom

2012-12-07 23:07:36.548 DemoVideo[699:1b803]email=Tom@yahoo.cn

2012-12-07 23:07:36.548 DemoVideo[699:1b803]=====================

2012-12-07 23:07:36.548 DemoVideo[699:1b803]=====================

2012-12-07 23:07:36.548 DemoVideo[699:1b803] name=LiLei

2012-12-07 23:07:36.549 DemoVideo[699:1b803]email=LiLei@yahoo.cn

2012-12-07 23:07:36.549 DemoVideo[699:1b803]=====================


    tempCard.name=@"CarBoon";

   tempCard.email=@"CarBoon@yahoo.cn";

    

    [tempCard print];

    

 

2012-12-07 23:07:50.844 DemoVideo[699:1b803]=====================

2012-12-07 23:07:50.844 DemoVideo[699:1b803]name=CarBoon

2012-12-07 23:07:50.844 DemoVideo[699:1b803]email=CarBoon@yahoo.cn

2012-12-07 23:07:50.845 DemoVideo[699:1b803]=====================


   // 输出objArray

   NSLog(@"objArray:     ");

    for (AddressCard *theCardin objArray) {

       [theCard print];

    }

    

 

2012-12-07 23:08:14.460 DemoVideo[699:1b803] objArray:     

2012-12-07 23:08:14.460 DemoVideo[699:1b803]=====================

2012-12-07 23:08:14.461 DemoVideo[699:1b803]name=CarBoon

2012-12-07 23:08:14.461 DemoVideo[699:1b803]email=CarBoon@yahoo.cn

2012-12-07 23:08:14.461 DemoVideo[699:1b803]=====================

2012-12-07 23:08:14.461 DemoVideo[699:1b803]=====================

2012-12-07 23:08:14.461 DemoVideo[699:1b803] name=LiLei

2012-12-07 23:08:14.462 DemoVideo[699:1b803]email=LiLei@yahoo.cn

2012-12-07 23:08:14.462 DemoVideo[699:1b803]=====================

    

   // 输出objArray2

   NSLog(@"objArray2:     ");

    for (AddressCard *theCardin objArray2) {

       [theCard print];

    }


 

2012-12-07 23:08:44.689 DemoVideo[699:1b803] objArray2:     

2012-12-07 23:08:45.493 DemoVideo[699:1b803]=====================

2012-12-07 23:08:45.493DemoVideo[699:1b803] name=CarBoon

2012-12-07 23:08:45.493DemoVideo[699:1b803] email=CarBoon@yahoo.cn

2012-12-07 23:08:45.493 DemoVideo[699:1b803]=====================

2012-12-07 23:08:46.021 DemoVideo[699:1b803]=====================

2012-12-07 23:08:46.021 DemoVideo[699:1b803] name=LiLei

2012-12-07 23:08:46.021 DemoVideo[699:1b803]email=LiLei@yahoo.cn

2012-12-07 23:08:46.021 DemoVideo[699:1b803]=====================


    [objArray2 release];


从输出结果,感觉差异的地方是最后输出的红色高亮部分!,objArray2=[objArray mutableCopy];
后,改变objArray中的对象,objArray2中响应的对象改变了!

为什么呢?

调用copy方法来拷贝不可变对象,或者调用mutableCopy方法拷贝可变对象时,

为新对象分配了内存空间,并且将对象数组中单个元素分别复制到新对象数组元素中。

对象默认为为浅复制,这种复制,仅仅是将引用从一个数组元素复制到另一个数组元素。

对,复制的是引用。所以,两个数组中的元素都指向内存中的同一个对象。

于是,这种情况就出现了,我们修改了原来数组中的对象,另一个数组中响应的元素也改变了。


还有一个需要注意的地方:
[objArray2 release];
根据上面的解释,对象被分配了空间,所以要我们手工进行释放!切记!

深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

但是,有时候,我们想能够拷贝一份值一样,但是互不影响的对象。那就要用到深拷贝!
深拷贝,就是为原对象拷贝一份结构和值相同的克隆对象,原对象与克隆对象占有不同的两块空间。这样,对原对象的修改不会影响到克隆对象;反之,亦然;
主要用到自己定义的类。因为默认,自己定义的类没有实现NSCopying协议和NSMutableCopying协议。
NSCopying协议:

-(id)copyWithZone:(NSZone *)zone;

NSMutableCopying协议

-(id)mutableCopyWithZone:(NSZone *)zone;


分别用来实现不可变对象的拷贝和可变对象的拷贝。
要实现自己类的拷贝,就要实现响应的协议,并且重写协议的响应方法。

代码如下:
在*.h中申明协议:

@interfaceAddressCard : NSObject<</span>NSCopying,NSMutableCopying>


在*.m中实现协议:

#pragma mark- NSCopying

-(id)copyWithZone:(NSZone *)zone{

    AddressCard *newCard=[[self class] allocWithZone:zone];

    newCard.name=_name;

    newCard.email=_email;

    newCard.salary=salary;

    return  newCard;


}


#pragma mark- NSMutableCopying

-(id)mutableCopyWithZone:(NSZone *)zone{

    AddressCard *newCard=[[self class] allocWithZone:zone];

   //[newCard setName:_name andEmail:_emailandSalary:salary];

    newCard.name=_name;

    newCard.email=_email;

    newCard.salary=salary;

    return  newCard;

    

}


使用时:

AddressCard *cloneCard=[card1copy];

    [cloneCardprint];


 

2012-12-08 22:31:06.206 DemoVideo[464:1b803]=====================

2012-12-08 22:31:06.207 DemoVideo[464:1b803] name=Tom

2012-12-08 22:31:06.207 DemoVideo[464:1b803]email=Tom@yahoo.cn

2012-12-08 22:31:06.207 DemoVideo[464:1b803]=====================


   card1.name=@"changeValue";

   card1.email=@"changeValue@yahoo.cn";

    [card1print];


 

2012-12-08 22:31:06.207 DemoVideo[464:1b803]=====================

2012-12-08 22:31:06.207 DemoVideo[464:1b803]name=changeValue

2012-12-08 22:31:06.207 DemoVideo[464:1b803]email=changeValue@yahoo.cn

2012-12-08 22:31:06.208 DemoVideo[464:1b803]=====================


    [cloneCardprint];


2012-12-08 22:31:22.731DemoVideo[464:1b803] =====================

2012-12-08 22:31:22.731DemoVideo[464:1b803] name=Tom

2012-12-08 22:31:22.731DemoVideo[464:1b803] email=Tom@yahoo.cn

2012-12-08 22:31:22.731DemoVideo[464:1b803] =====================


从输出可见,card1cloneCard占有不同的内存空间!





0 0
原创粉丝点击