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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© doudou33420 中级黑马   /  2014-11-4 23:32  /  1791 人查看  /  5 人回复  /   4 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 doudou33420 于 2014-11-4 23:35 编辑

对象的浅拷贝和深拷贝  李明杰没讲这方面的知识, 视频里好像连copy都没讲
不过这个真的要了解一下.. 没看过的 补充一下吧

  1. 对象的拷贝分为浅拷贝和深拷贝,浅拷贝就是只拷贝对象,但是属性不拷贝,拷贝出来的对象和原来的对象共用属性,即指向同一个属性地址,深拷贝则相当于不仅拷贝了一个对象还拷贝了它的属性,即完全是两个东西,只不过内容相同而已。

  2. 拷贝用到协议,如果这个类创建对象后,这个对象要被拷贝,那么这个类就需要用到拷贝协议,分两种:<NSCopying>和<NSMutableCopying>相当于一个是拷贝,另一个是拷贝后可修改。

  3. (1)浅拷贝的案例。有一个Person类,它创建一个person1对象后,用person1再拷贝一个person2出来。

  4. //Person类的Person.h文件
  5. #import <Foundation/Foundation.h>
  6. //因为这个类要支持拷贝,所以需要引入拷贝协议,有两种,后一种拷贝后可修改
  7. @interface Person : NSObject<NSCopying,NSMutableCopying>
  8. @property(nonatomic,copy) NSString* name;
  9. @property(nonatomic,retain) NSNumber* age;
  10. @end
  11. //这是Person.m文件
  12. #import "Person.h"
  13. @implementation Person
  14. //这是系统函数,可以直接拷贝过来
  15. - (id)copyWithZone:(NSZone *)zone{
  16.   Person *person=[[[self class]allocWithZone:zone]init]; //默认格式
  17.   person.name=_name; //浅拷贝就是直接赋值即可
  18.   person.age=_age;  //浅拷贝就是直接赋值即可
  19.   return person;
  20. }
  21. @end
  22. //main.m文件
  23. #import <Foundation/Foundation.h>
  24. #import "Person.h"//记得引入头文件
  25. int main(int argc, const char * argv[])
  26. {
  27.   @autoreleasepool {
  28.     Person *person1=[[Person alloc]init];
  29.     person1.name=@"jack";
  30.     person1.age=@18;
  31.     Person *person2=[person1 copy];
  32.     NSLog(@"%p,%p",person1,person2);//输入两个对象地址,不同
  33.     NSLog(@"%p,%p",person1.age,person2.age);//输出两个对象的属性地址,相同
  34.   }
  35.   return 0;
  36. }
  37. 结果:

  38. 0x1002036f0,0x100200330 //不同
  39. 0x1227,0x1227 //相同
  40. (2)深拷贝的案例。

  41. 按道理是只需要把Person.m里面的赋值语句改成下面的样子,就能实现深拷贝:

  42. person.name=[_name copy];
  43. person.age=[_age copy];
  44. 但是,因为cocoa优化过了,所以有如下规则:

  45. a:如果是Foundation框架里地不可变对象,就是Array,NSString等创建的对象,直接用copy来拷贝相当于retain,也就是属性还是同一个;

  46. b:如果是用mutableCopy来拷贝,不管是可变还是不可变对象,属性神马的都直接拷贝了一份,即真正意义上得拷贝,它拷贝出来的对象统统都是可变的;

  47. c:如果是可变对象,我们用copy也能实现真正意义上的拷贝,但是拷贝出来的对象是不可变的。

  48. 所以,我们拿name实验(因为age没有mutableCopy)实现语句的修改:

  49. person.name=[_name mutableCopy]
  50. person.age=[_age copy];
  51. 然后再输出person1和person2的name属性的地址,发现就不同了。
复制代码





评分

参与人数 1技术分 +1 收起 理由
星河鹭起 + 1

查看全部评分

5 个回复

正序浏览
好,32个赞
回复 使用道具 举报
非常 感谢   收获不小     大家一起加油哦:handshake
回复 使用道具 举报
   谢谢  分享
回复 使用道具 举报
arui12580 来自手机 中级黑马 2014-12-15 23:06:39
藤椅
深浅复制确实没讲到,但是挺重要的。
回复 使用道具 举报
谢谢,不是好像,是真的没讲
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马