黑马程序员技术交流社区
标题: 说说深复制和浅复制 [打印本页]
作者: 小叶子 时间: 2014-9-28 11:40
标题: 说说深复制和浅复制
本帖最后由 小叶子 于 2014-9-28 11:50 编辑
深复制和浅复制
个人见解,欢迎探讨,部分观点来自网上.
简单的来说就是,在有指针的情况下.浅拷贝只是增加了一个指针指向已经存在的内存(地址),而深拷贝就是增加一个指针并且申请一个新的内存(地址),使这个增加的指针指向这个新的内存.采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误!
乍看,不就是copy和ratain吗?
retain是浅拷贝,copy是深拷贝?不一定.
说到这儿,又要想起copy和mutabCop:
copy语法的目的:改变副本的时候,不会影响到源对象;
深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。
浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。
拷贝有下面两个方法实现拷贝:
- <blockquote>- (id)copy;
- - (id)mutableCopy;
复制代码
要实现copy,必须实现<NSCopying>协议
数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例,其他的同理:
1.不可变字符串调用copy实现拷(浅拷贝)
- NSString *string = [[NSString alloc] initWithFormat: @"abcde"];
- // copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身
- // 源对象计数器会+1
- // 在浅拷贝情况下,copy其实就相当于retain
- NSString *str = [string copy];
复制代码
2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)
- NSString *string = [[NSString alloc] initWithFormat: @"abcd"];
- // 产生了一个新的对象,计数器为1。源对象的计数器不变。
- NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1
- // str和string不是相同对象
- // NSLog(@"%i", str == string);//0
- [str appendString: @" abcd"];//修改str不影响string
- NSLog(@"string: %@", string);
- NSLog(@"str:%@", str);
复制代码
3.可变字符串调用copy实现拷贝(深拷贝)
- NSMutableString *string = [NSMutableString stringWithFormat : @"age is %i", 10];
- // 会产生一个新对象,str计数器为1
- NSString *str = [string copy];
复制代码
4.可变字符串的MutableCopy(深拷贝)
- NSMutableString *string = [NSMutableString stringWithFormat : @"age is %i", 10];
- // 会产生一个新对象,str计数器为1
- NSMutableString *str = [string mutableCopy];
- [str appendString: @"1234"];//修改新对象不影响原对象
- NSLog(@"str: %@", str);
- NSLog(@"string: %@", string);
复制代码
5.拷贝自定义对象,下面以Student对象为例
a.Student要实现copy,必须实现<NSCopying>协议
b.实现<NSCopying>协议的方法:
- - (id)copyWithZone: (NSZone *)zone
复制代码
Student.h文件
____________________________________________________________________
- @interface Student : NSObject <NSCopying>
- // copy代表set方法会release旧对象、copy新对象
- // 修改外面的变量,并不会影响到内部的成员变量
- // 建议:NSString一般用copy策略,其他对象一般用retain
- @property (nonatomic, copy) NSString *name;
- + (id)studentWithName: (NSString *)name;
- @end
复制代码
Student.m文件
____________________________________________________________________
- #import "Student.h"
- @implementation Student
- + (id)studentWithName: (NSString *)name {
- // 这里最好写[self class]
- Student *stu = [[[[self class] alloc] init] autorelease];
- stu.name = name;
- return stu;
- }
- - (void)dealloc {
- [_name release];
- [super dealloc];
- }
- #pragma mark description方法内部不能打印self,不然会造成死循环
- - (NSString *)description {
- return [NSString stringWithFormat: @"[name=%@]", _name];
- }
- #pragma mark copying协议的方法
- // 这里创建的副本对象不要求释放
- - (id)copyWithZone: (NSZone *)zone {
- Student *copy = [[[self class] allocWithZone:zone] init];
- // 拷贝名字给副本对象
- copy.name = self.name;
- return copy;
- }
- @end
复制代码
拷贝student
____________________________________________________________________
拷贝Student
- <blockquote>
- Student *stu1 = [Student studentWithName: @"stu1"];
- Student *stu2 = [stu1 copy];
- stu2.name = @"stu2";
- NSLog(@"stu1: %@", stu1);
- NSLog(@"stu2: %@", stu2);
- [stu2 release];
复制代码
小结:
建议:NSString一般用copy策略,其他对象一般用retain;
只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;
作者: zrtalent 时间: 2014-10-5 14:45
哥们, 你成功参加到黑马的三期培训了吗?看你这几天一直没有帖子了,关注你好久了。
作者: 超越自己 时间: 2014-10-5 21:56
学习了。。
作者: 小叶子 时间: 2014-10-7 00:24
嗯。。谢谢你的支持。
作者: zrtalent 时间: 2014-10-7 14:43
我过几天就提交视频面试了,你当时面试的时候都问的哪些问题啊?我现在心里没有什么底。C多还是OC多啊?
作者: 小叶子 时间: 2014-10-7 17:33
C和OC都在问,理论题多看看又个ppt文档还是啥的吧~
OC的在PPT03-Objective-C里面~
放轻松,不难
作者: zrtalent 时间: 2014-10-7 19:21
太感谢了,我现在不算面试64.5分,以你过来人的身份来看,我要是赶在10月20日之前完成面试,然后申请入学名额那我总分得多少才够啊?10月20日是第四期的第一批次录取。:dizzy:
作者: 小叶子 时间: 2014-10-7 19:50
别怪我乌鸦嘴~~~~我就说说,你别当真
试试吧,就算第一次分不高,还有二次嘛~~~~也许第一次人不多
作者: zrtalent 时间: 2014-10-7 20:35
叶子大哥。你给我的帖子我早就看了,你这个给我的一个晴天霹雳啊!久久不能平复啊!你当时录取的是第几批次啊?总分是多少啊?都问你的最后的编程题还能想起来都有哪些了吗?我看你得了41.5分啊?能分享我点秘诀吗?我是蔡老师,但是我看她好像挺严啊。完了完了。。。
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |