深拷贝和浅拷贝详解
来源:互联网 发布:中国谁靠卖域名发财 编辑:程序博客网 时间:2024/05/26 02:55
深拷贝和浅拷贝
用一句简单的话来说就是浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
下面看copy和mutableCopy
copy和mutableCopy。这两个方法都是返回一个id类型的对象,那么这两者之间有什么区别呢?根据官方文档解释,copy方法,返回copyWithZone方法返回的对象(Returns the object returned by copyWithZone:)。而mutableCopy方法,返回mutableCopyWithZone方法返回的对象(Returns the object returned by mutableCopyWithZone:)。简单理解就是调用copy就是调用copyWithZone,调用mutableCopy就是调用mutableCopyWithZone。那么有什么区别呢?
mutableCopy:mutableCopy,使用它copy出来的对象是可以对其内容进行改变的。
copy:copy,使用它复制出来的对象,其内容是不可以改变的。
MutableCopy:可变拷贝,其拷贝过程就是在内存中重新开辟一块区域,将对象复制一份放到这个区域。新对象是可以改变的,而且新对象的改变对源对象是没有影响的。
copy:不可变copy,同样也是要开辟一段内存空间给新对象,但新对象是不可以改变的。(特殊情况:不可变->不可变的拷贝,是不创建新内存空间的)
(注:这里的可变copy和不可变copy是相对Foundation框架的类而言的,如果我们自己定义的类实现copy,都是可变的)。
接下来我们以NSString为例子,来说明copy和mutableCopy的区别。
-(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中并不是所有的对象都支持copy,mutableCopy,遵守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
- 深拷贝和浅拷贝详解
- 浅拷贝和深拷贝详解
- JS浅拷贝和深拷贝详解
- 浅拷贝和深拷贝
- 浅拷贝和深拷贝
- 浅拷贝和深拷贝
- 深拷贝和浅拷贝
- 深拷贝和浅拷贝
- 深拷贝和浅拷贝
- 浅拷贝和深拷贝
- 浅拷贝和深拷贝
- 深拷贝和浅拷贝
- 深拷贝和浅拷贝
- 浅拷贝和深拷贝
- 浅拷贝和深拷贝
- 浅拷贝和深拷贝
- 深拷贝 和 浅拷贝
- 浅拷贝和深拷贝
- Cookie/Session机制详解
- xcode7上传appstore,shareSDK TencentOpenApi_IOS_Bundle.bundle报错问题的解决方法
- Log4j实现对Java日志的配置全攻略
- android studio 报错Error:Execution failed for task ':app:packageRelease'. 解决方法
- Linux下安装matlab
- 深拷贝和浅拷贝详解
- Cocos2dx -- 入门之 lua 调用 c++
- 通过 Spring AOP 验证方法的参数是否合法
- 编译CTK
- 关于hibernate中@Transient注解使用的一点心得
- 各种编码的由来(很通俗)
- tomcat manager the Cross Origin Resource Sharing
- Android应用系列:值得收藏的ViewHolder工具类实现
- 关于ActiveMQ的一点总结