A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小叶子 中级黑马   /  2014-9-28 11:40  /  2094 人查看  /  8 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小叶子 于 2014-9-28 11:50 编辑

深复制和浅复制

个人见解,欢迎探讨,部分观点来自网上.

简单的来说就是,在有指针的情况下.浅拷贝只是增加了一个指针指向已经存在的内存(地址),而深拷贝就是增加一个指针并且申请一个新的内存(地址),使这个增加的指针指向这个新的内存.采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误!
乍看,不就是copy和ratain吗?
retain是浅拷贝,copy是深拷贝?不一定.


说到这儿,又要想起copy和mutabCop:


copy语法的目的:改变副本的时候,不会影响到源对象;
深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。
拷贝有下面两个方法实现拷贝:

  1. <blockquote>- (id)copy;
  2. - (id)mutableCopy;
复制代码



要实现copy,必须实现<NSCopying>协议
数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例,其他的同理:
1.不可变字符串调用copy实现拷(浅拷贝)

  1. NSString *string = [[NSString alloc] initWithFormat: @"abcde"];
  2. // copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身
  3. // 源对象计数器会+1
  4. // 在浅拷贝情况下,copy其实就相当于retain
  5. NSString *str = [string copy];
复制代码



2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)

  1. NSString *string = [[NSString alloc] initWithFormat: @"abcd"];
  2. // 产生了一个新的对象,计数器为1。源对象的计数器不变。
  3. NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1
  4. // str和string不是相同对象
  5. // NSLog(@"%i", str == string);//0
  6. [str appendString: @" abcd"];//修改str不影响string
  7. NSLog(@"string: %@", string);
  8. NSLog(@"str:%@", str);
复制代码



3.可变字符串调用copy实现拷贝(深拷贝)

  1. NSMutableString *string = [NSMutableString stringWithFormat : @"age is %i", 10];
  2. // 会产生一个新对象,str计数器为1
  3. NSString *str = [string copy];
复制代码



4.可变字符串的MutableCopy(深拷贝)

  1. NSMutableString *string = [NSMutableString stringWithFormat : @"age is %i", 10];
  2. // 会产生一个新对象,str计数器为1
  3. NSMutableString *str = [string mutableCopy];
  4. [str appendString: @"1234"];//修改新对象不影响原对象
  5. NSLog(@"str: %@", str);
  6. NSLog(@"string: %@", string);
复制代码



5.拷贝自定义对象,下面以Student对象为例
a.Student要实现copy,必须实现<NSCopying>协议
b.实现<NSCopying>协议的方法:
  1. - (id)copyWithZone: (NSZone *)zone
复制代码


Student.h文件


____________________________________________________________________

  1. @interface Student : NSObject <NSCopying>

  2. // copy代表set方法会release旧对象、copy新对象
  3. // 修改外面的变量,并不会影响到内部的成员变量
  4. // 建议:NSString一般用copy策略,其他对象一般用retain
  5. @property (nonatomic, copy) NSString *name;

  6. + (id)studentWithName: (NSString *)name;

  7. @end
复制代码



Student.m文件

____________________________________________________________________  


  1. #import "Student.h"

  2. @implementation Student

  3. + (id)studentWithName: (NSString *)name {
  4. // 这里最好写[self class]
  5. Student *stu = [[[[self class] alloc] init] autorelease];
  6. stu.name = name;

  7. return stu;
  8. }

  9. - (void)dealloc {
  10. [_name release];

  11. [super dealloc];
  12. }

  13. #pragma mark description方法内部不能打印self,不然会造成死循环
  14. - (NSString *)description {
  15. return [NSString stringWithFormat: @"[name=%@]", _name];
  16. }

  17. #pragma mark copying协议的方法
  18. // 这里创建的副本对象不要求释放
  19. - (id)copyWithZone: (NSZone *)zone {
  20. Student *copy = [[[self class] allocWithZone:zone] init];

  21. // 拷贝名字给副本对象
  22. copy.name = self.name;

  23. return copy;
  24. }

  25. @end
复制代码




拷贝student

____________________________________________________________________
拷贝Student
  1. <blockquote>
  2. Student *stu1 = [Student studentWithName: @"stu1"];

  3. Student *stu2 = [stu1 copy];
  4. stu2.name = @"stu2";

  5. NSLog(@"stu1: %@", stu1);
  6. NSLog(@"stu2: %@", stu2);

  7. [stu2 release];
复制代码




小结:
建议:NSString一般用copy策略,其他对象一般用retain;

只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;






8 个回复

倒序浏览
哥们, 你成功参加到黑马的三期培训了吗?看你这几天一直没有帖子了,关注你好久了。
回复 使用道具 举报
学习了。。
回复 使用道具 举报
zrtalent 发表于 2014-10-5 14:45
哥们, 你成功参加到黑马的三期培训了吗?看你这几天一直没有帖子了,关注你好久了。 ...

嗯。。谢谢你的支持。
回复 使用道具 举报
小叶子 发表于 2014-10-7 00:24
嗯。。谢谢你的支持。

我过几天就提交视频面试了,你当时面试的时候都问的哪些问题啊?我现在心里没有什么底。C多还是OC多啊?
回复 使用道具 举报
zrtalent 发表于 2014-10-7 14:43
我过几天就提交视频面试了,你当时面试的时候都问的哪些问题啊?我现在心里没有什么底。C多还是OC多啊? ...

C和OC都在问,理论题多看看又个ppt文档还是啥的吧~

OC的在PPT03-Objective-C里面~

放轻松,不难
回复 使用道具 举报
小叶子 发表于 2014-10-7 17:33
C和OC都在问,理论题多看看又个ppt文档还是啥的吧~

OC的在PPT03-Objective-C里面~

太感谢了,我现在不算面试64.5分,以你过来人的身份来看,我要是赶在10月20日之前完成面试,然后申请入学名额那我总分得多少才够啊?10月20日是第四期的第一批次录取。:dizzy:
回复 使用道具 举报
zrtalent 发表于 2014-10-7 19:21
太感谢了,我现在不算面试64.5分,以你过来人的身份来看,我要是赶在10月20日之前完成面试,然后申请入学 ...


别怪我乌鸦嘴~~~~我就说说,你别当真
试试吧,就算第一次分不高,还有二次嘛~~~~也许第一次人不多
回复 使用道具 举报
小叶子 发表于 2014-10-7 19:50
别怪我乌鸦嘴~~~~我就说说,你别当真
试试吧,就算第一次分不高,还有二次嘛~~~~也许第一次人不多 ...

叶子大哥。你给我的帖子我早就看了,你这个给我的一个晴天霹雳啊!久久不能平复啊!你当时录取的是第几批次啊?总分是多少啊?都问你的最后的编程题还能想起来都有哪些了吗?我看你得了41.5分啊?能分享我点秘诀吗?我是蔡老师,但是我看她好像挺严啊。完了完了。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马