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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

刘昭

中级黑马

  • 黑马币:20

  • 帖子:46

  • 精华:0

© 刘昭 中级黑马   /  2014-6-25 15:52  /  6682 人查看  /  16 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘昭 于 2014-6-28 14:09 编辑

在视频里看到深拷贝和浅拷贝,
copy 、 retain 、mutableCopy在什么时候使用,有什么区别?
是不是copy 、 retain 就是浅拷贝,mutableCopy就是深拷贝?

评分

参与人数 1技术分 +1 收起 理由
傘が咲く + 1

查看全部评分

16 个回复

倒序浏览
看我的贴!
回复 使用道具 举报

nanzu 同学  ,没有看见这个问题的贴子啊~
你都没写标题,不好找
回复 使用道具 举报
OC的东西啊 你看视频速度很快呀
回复 使用道具 举报
抱0抱 发表于 2014-6-26 18:29
OC的东西啊 你看视频速度很快呀

我跳着看的,c的还没看....
回复 使用道具 举报
刘昭 发表于 2014-6-27 18:06
我跳着看的,c的还没看....

入学测试的东西都是OC的 所以你可以考虑考虑 我现在看OC看的比较蒙
回复 使用道具 举报
不能说retain是浅拷贝,
因为浅拷贝被的定义是:指针拷贝,源文件和新文件指向的是同一个地址,也就是说浅拷贝要复出出来一个新的文件,但两个文件的地址还是一个。浅拷贝的话是只有不可变数组(如:NSArray,NSSet,NS字典)遇上copy,才是浅拷贝,剩下的都是深拷贝。

深拷贝的定义是:内容复制,也就是还是要复制出来一个新的对象,但新对象和原来对象的地址是两个完全没有关系的地址。改变新对象,旧对象就不会改变。改变旧对象新对象就不会改变。他的引用计数器是旧对象不变,新对象的retainCount + 1 .


而 retain  他只是让引用计数器加1 。 并没有让旧对象复制出来一个新的对象。

评分

参与人数 1技术分 +1 收起 理由
傘が咲く + 1

查看全部评分

回复 使用道具 举报 1 0
libra 中级黑马 2014-6-28 10:12:44
8#
还没看到存储器管理。。
回复 使用道具 举报
刘昭 中级黑马 2014-6-28 12:46:07
9#
m573555543 发表于 2014-6-28 09:29
不能说retain是浅拷贝,
因为浅拷贝被的定义是:指针拷贝,源文件和新文件指向的是同一个地址,也就是说浅 ...

噢 , 终于懂了.....
只有不可变的数组Copy才是浅拷贝,而且浅拷贝只是拷贝了对象的指针。
回复 使用道具 举报
深拷贝:深拷贝就是新建一个对象和新开辟一块内存。
浅拷贝:浅拷贝就是新建一个对象,但是都指向同一块内存地址。
回复 使用道具 举报
TLTY 初级黑马 2014-6-28 13:13:27
11#
你可以在百度上查啊,关于深拷贝和浅拷贝有很多博客都写得很详细
回复 使用道具 举报
Littlekin 发表于 2014-6-28 12:54
深拷贝:深拷贝就是新建一个对象和新开辟一块内存。
浅拷贝:浅拷贝就是新建一个对象,但是都指向同一块内 ...

嗯,对啊
理解了  
浅拷贝就是只复制了原对象的指针,指向的还是原对象的内容。
而深拷贝是新建了一个对象,复制了原对象的内容。
回复 使用道具 举报
TLTY 发表于 2014-6-28 13:13
你可以在百度上查啊,关于深拷贝和浅拷贝有很多博客都写得很详细

嗯,好的,谢谢哈~~~
这是新人贴,我先来试试水~~
回复 使用道具 举报
浅复制和深复制是对于包含对象成员的对象而言的。
浅复制:只复制对象本身,对象的成员只复制指针。
深复制:在浅复制的基础上,同时复制对象的成员。
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着
回复 使用道具 举报
TLTY 初级黑马 2014-6-28 14:05:25
15#
刘昭 发表于 2014-6-28 13:19
嗯,好的,谢谢哈~~~
这是新人贴,我先来试试水~~

呵呵,我也是,正在为技术分奋斗呢
回复 使用道具 举报
a1130003724 发表于 2014-6-28 13:53
浅复制和深复制是对于包含对象成员的对象而言的。
浅复制:只复制对象本身,对象的成员只复制指针。
深复制 ...

呃,比喻得好生动~~~
回复 使用道具 举报
以下内容转自被人博客
  1. copy设计的目的:改变副本的时候,不会影响到原来的对象
  2. 1、一个对象使用copy或者mutableCopy方法可以创建对象的副本
  3. 2、copy需要先实现NSCopying协议,创建的是不可改变副本(NSString、NSArray、NSDictionary)
  4. mutableCopy 需要先实现NSMutableCopying协议,创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
  5. 3、深复制:内容拷贝,源对象和副本指向的是同一个对象。源对象引用计数器不变,副本计数器设置为1
  6. 浅复制:指针复制,源对象和副本对象指向的二十同一个对象,对象的引用对象加1,其实相当于做了一次retain操作
  7. 只有不可变对象创建不可变副本(copy)才是浅复制,其它都是深复制

  8. 4、NSString、NSArray、NSDictionary三种OC对象默认都已经实现了cooppying和NSMutableCopying协议

  9. 5、自定义类添加复制功能:
  10. 如果想自定义copy,那么必须遵守NSCopying,并实现copyWithZone:方法
  11. 如果想自定义mutableCopy,那么就必须遵守NSMutableCopying,并实现mutableCopyZone:方法
  12. 例如copy:
  13. 建议用self class 代替类名

  14. - (id)copyWithZone:(NSZone *)zone{
  15.     id copy = [[[self class] allocWithZone:zone] init];
  16.     //这儿开始做一些属性的初始化
  17.     return copy;
  18. }

  19. 测试demo代码如下:
  20. 在这个demo中主要演示copy、mutableCopy,解说深拷贝、浅拷贝
  21. 以及自定义copy、mutableCopy的方法

  22. Student.h文件
  23. #import <Foundation/Foundation.h>
  24. @interface Student : NSObject<NSCopying>
  25. //copy代表set方法会release旧对象,copy新对象
  26. //修改外面的变量,并不会影响到内部的成员变量
  27. //建议:NSString一般用copy策略,其它对象一般用retain
  28. //retain 和外边是同一个对象,外边该了,里面这个name属性也会改
  29. @property (nonatomic, retain) NSString *name;

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

  31. @end

  32. Student.m文件:
  33. #import "Student.h"
  34. @implementation Student
  35. /**
  36. //@property (copy) :的意思如同下面这段setName方法
  37. - (void)setName:(NSString *)name{
  38.     if(_name!=name){
  39.         [_name release];
  40.         _name = [name copy];
  41.     }
  42. }
  43. **/

  44. + (id)studentWithName:(NSString *)name{
  45.     //最好写slef class
  46.     Student *stu = [[[[self class] alloc] init] autorelease];
  47.     stu.name = name;
  48.     return stu;
  49. }

  50. #pragma mark coping协议的方法
  51. //这里创建的副本对象不要求释放
  52. - (id)copyWithZone:(NSZone *)zone{
  53.     Student *copy = [[[self class] allocWithZone:zone]init];
  54.     copy.name = self.name;
  55.     return copy;
  56. }
  57. //description 内部不能打印self不然会有死循环
  58. - (NSString *)description{
  59.     return [NSString stringWithFormat:@"name=%@",_name];
  60. }

  61. - (void) dealloc{
  62.     NSLog(@"student %@ is destoryed", self);
  63.     [_name release];
  64.     [super dealloc];
  65. }

  66. @end

  67. GoodStudent.h文件:
  68. #import "Student.h"
  69. @interface GoodStudent : Student

  70. @property (nonatomic, assign) int age;

  71. + (id) goodStudentWithAge:(int) age name:(NSString *)name;

  72. @end

  73. GoodStudent.m文件:

  74. #import "GoodStudent.h"
  75. @implementation GoodStudent
  76. + (id)goodStudentWithAge:(int)age name:(NSString *)name{
  77.     GoodStudent *good = [GoodStudent studentWithName:name];
  78.     good.age = age;
  79.     return good ;
  80. }

  81. #pragma mark 重写父类的方法
  82. - (id)copyWithZone:(NSZone *)zone{
  83.     //一定要调用父类的这个方法,因为父类帮我们copy了名字
  84.     GoodStudent *copy = [super copyWithZone:zone];
  85.     copy.age = self.age;
  86.     return copy;
  87. }

  88. - (NSString *)description{
  89.     return [NSString stringWithFormat:@"[name=%@, age=%i]",self.name, _age];
  90. }
  91. @end

  92. main测试方法:

  93. #import <Foundation/Foundation.h>
  94. #import "Student.h"
  95. #import "GoodStudent.h"

  96. void stringMutableCopy(){
  97.     NSString *string = [[NSString alloc] initWithFormat:@"age is %i",10];
  98.     //产生一个新的对象,计数器为1,源对象的计数器不改变
  99.     NSMutableString *str = [string  mutableCopy];
  100.    
  101.     NSLog(@"string: %zi",[string retainCount]); //1
  102.     NSLog(@"str :%zi",[str retainCount]);  //1
  103.     //str和string不是相同对象
  104.     NSLog(@"%i",str ==string);//0
  105.    
  106.     [str release];
  107.     [string release];
  108.    
  109. }
  110. /**
  111. 只有这一种情况是浅拷贝:指针拷贝,不会产生新的对象
  112. **/
  113. void stringCopy(){
  114.     NSString *string = [[NSString alloc] initWithFormat:@"age is %i",10];
  115.     //copy是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy直接返回源对象本身
  116.    // 源对象计数器+1
  117.     NSString *str = [string copy];

  118.     NSLog(@"%zi",[string retainCount]); //2
  119.     NSLog(@"%zi",[str retainCount]); //2
  120.     //相同对象
  121.     NSLog(@"%i",str == string);  //1
  122.    
  123.     [str release];
  124.     [string release];
  125. }
  126. /**
  127. 只有一种情况浅拷贝:string-string
  128. **/

  129.     // 定义个字符串
  130.     NSString *s1 = @"itheima";
  131.    
  132.     // 浅复制
  133.     NSString *s2 = [s1 copy];
  134. //深拷贝  【这地方本人是有疑惑的,怀疑原博客主人写错了】
  135. void mutableStringCopy(){
  136.     NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i",10];
  137.     NSString *str = [string copy];
  138.    
  139.     NSLog(@"%i",str == string); //0
  140. }
  141. //深拷贝
  142. void mutableStringMutableCopy(){
  143.     NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i",10];
  144.     NSMutableString *str = [string mutableCopy];
  145.     NSLog(@"%i",str == string ); //0
  146.    
  147.     [str appendString:@"abc"];
  148.     NSLog(@"%@", str); //10abc
  149.    
  150. }
  151. //stendent属性的copy
  152. void studentNameCopy(){
  153.     Student *stu = [[[Student alloc]init] autorelease];
  154.     NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
  155.    
  156.     stu.name = string;
  157.    
  158.     [string appendString:@"abcd"];
  159.    
  160.     NSLog(@"stu.name=%@",stu.name);
  161.     NSLog(@"string=%@",string);
  162. }
  163. //stendent对象的copy
  164. void studentCopy(){
  165.     Student *stu1 = [Student studentWithName:@"stu1"];
  166.     Student *stu2 = [stu1 copy];
  167.    
  168.     NSLog(@"stu1:%@",stu1.name);
  169.     NSLog(@"stu2:%@",stu2.name);
  170.    
  171.     stu2.name = @"stu2";
  172.    
  173.     NSLog(@"stu1:%@",stu1.name);
  174.     NSLog(@"stu2:%@",stu2.name);
  175.     NSLog(@"%i",stu1 == stu2);
  176.    
  177.     [stu2 release];
  178. }
  179. //GoodStudent子类的copy
  180. void goodStudent(){
  181.     GoodStudent *goodStu1= [GoodStudent goodStudentWithAge:20 name:@"goodStu1"];
  182.     NSLog(@"goodStu1:%@",goodStu1);
  183.    
  184.     GoodStudent *goodStu2 = [goodStu1 copy];
  185.     NSLog(@"goodStu2:%@",goodStu2);
  186. }
  187. int main(int argc, const char * argv[])
  188. {

  189.     @autoreleasepool {
  190.         NSLog(@"----stringMutableCopy----");
  191.         stringMutableCopy();
  192.         NSLog(@"----stringcopy----");
  193.         stringCopy();
  194.         NSLog(@"----mutableStringCopy----");
  195.         mutableStringCopy();
  196.         NSLog(@"----mutableStringMutableCopy----");
  197.         mutableStringMutableCopy();
  198.         NSLog(@"----studentNameCopy----");
  199.         studentNameCopy();
  200.         NSLog(@"----studentCopy----");
  201.         studentCopy();
  202.         NSLog(@"----goodStudent----");
  203.         goodStudent();
  204.     }
  205.     return 0;
  206. }
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马