深拷贝和浅拷贝详解

来源:互联网 发布:中国谁靠卖域名发财 编辑:程序博客网 时间:2024/05/26 02:55

深拷贝和浅拷贝 


      用一句简单的话来说就是浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。


下面看copymutableCopy


   copymutableCopy。这两个方法都是返回一个id类型的对象,那么这两者之间有什么区别呢?根据官方文档解释,copy方法,返回copyWithZone方法返回的对象(Returns the object returned by copyWithZone:)。而mutableCopy方法,返回mutableCopyWithZone方法返回的对象(Returns the object returned by mutableCopyWithZone:)。简单理解就是调用copy就是调用copyWithZone,调用mutableCopy就是调用mutableCopyWithZone。那么有什么区别呢?

 

 mutableCopy:mutableCopy,使用它copy出来的对象是可以对其内容进行改变的。

 copycopy,使用它复制出来的对象,其内容是不可以改变的。

 

 MutableCopy:可变拷贝,其拷贝过程就是在内存中重新开辟一块区域,将对象复制一份放到这个区域。新对象是可以改变的,而且新对象的改变对源对象是没有影响的。

 copy:不可变copy,同样也是要开辟一段内存空间给新对象,但新对象是不可以改变的。(特殊情况:不可变->不可变的拷贝,是不创建新内存空间的)

(注:这里的可变copy和不可变copy是相对Foundation框架的类而言的,如果我们自己定义的类实现copy,都是可变的)。

 

接下来我们以NSString为例子,来说明copymutableCopy的区别。

-(void)testString{    //1创建一个可变字符串    NSMutableString *name=[NSMutableString stringWithString:@"Jack"];    NSLog(@"源字符串: %p---%@",name,name);// %p 指针,%@ 对象        //可变->可变    NSMutableString *nameOne=[name mutableCopy];    [nameOne appendString:@"Long"];    NSLog(@"可变字符串: %p---%@",nameOne,nameOne);        //可变->不可变    NSString *nameTwo=[name copy];    //NSMutableString *nameTwo2=[name copy];    //[nameTwo2 appendString:@"22"]; 对于不可变对象使用可变对象接收并使用相应的方法,运行报错。    NSLog(@"不可变字符串:%p---%@",nameTwo,nameTwo);        NSLog(@"--------不可变字符串部分----------");    //2创建一个不可变字符串    NSString *age=@"24";    NSLog(@"源字符串:%p---%@",age,age);        //不可变->不可变    NSString *anotherAge=[age copy];    NSLog(@"不可变字符串: %p---%@",anotherAge,anotherAge);        //不可变->可变    NSMutableString *mutableAge=[age mutableCopy];    NSLog(@"可变字符串: %p---%@",mutableAge,mutableAge);        /*     源字符串:   0x7b077620---Jack     可变字符串: 0x79e0bb70---JackLong     不可变字符串:0x79e04f80---Jack     --------不可变字符串部分----------     源字符串:   0xaf090---24     不可变字符串: 0xaf090---24     可变字符串:  0x79e08f30---24     */        由打印结果可知:对不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。    简单一点就是, copy : 对于不可变对象是浅拷贝,对于其他对象都是深拷贝。mutablecopy:对于所有的对象都是深拷贝.}


 ios中并不是所有的对象都支持copymutableCopy,遵守NSCopying协议的类可以发送copy消息,遵守NSMutableCopying协议的类才可以发送mutableCopy消息。假如发送了一个没有遵守上诉两协议而发送 copy或者 mutableCopy,那么就会发生异常。但是默认的ios类并没有遵守这两个协议。如果想自定义一下copy那么就必须遵守NSCopying,并且实现 copyWithZone:方法,如果想自定义一下mutableCopy那么就必须遵守NSMutableCopying,并且实现 mutableCopyWithZone:方法。


下面自定义类遵守NSCopying和NSMutableCopying协议。(也可以只遵守其中的一个进行相应的copy操作)

#import <Foundation/Foundation.h>//注意:自定义对象都是可变的@interface Person : NSObject<NSCopying,NSMutableCopying>@property (nonatomic, copy) NSString *name;@property (nonatomic, assign) NSInteger age;@end#import "Person.h"@implementation Person- (id)copyWithZone:(NSZone *)zone{    Person *p = [[[self class] allocWithZone:zone] init];        p.name = self.name;    p.age = self.age;        return p;}- (NSString *)description{    return [NSString stringWithFormat:@"%@ %p : name %@", self.class, self, self.name];}-(id)mutableCopyWithZone:(NSZone *)zone{    Person *p = [[[self class] allocWithZone:zone]init];        p.name = self.name;    p.age = self.age;        return p;}@end

测试自定义Person对象 

-(void)testCustomPersonObject{    Person *p = [[Person alloc] init];    p.name = @"Jack";        Person *p1 = [p copy];    p1.name = @"shi";        //注意:这里如果没有NSMutableCopying协议并且实现mutableCopyWithZone方法,那么不能够使用mutableCopy进行可变拷贝,因为自定义对象并没有遵守协议,所以直接运行出错!如果遵守了NSMutableCopying并且实现了mutableCopyWithZone方法,那么就ok了!    Person *p2 = [p mutableCopy];    p2.name = @"hua";        NSLog(@"Person对象:%@ %@ %@", p, p1,p2);    NSLog(@"Person指针:%p %p", p, p1);        /*     Person对象:Person 0x79e6e260 : name Jack Person 0x79e6d500 : name shi Person 0x79e6d510 : name hua     Person指针:0x79e6e260 0x79e6d500     */}

相关文章:

http://www.cocoachina.com/ios/20151202/14520.html

0 0
原创粉丝点击