copy,mutableCopy 理解

copy,mutableCopy 理解
好记性不如烂笔头,好理解不如写出来,前一句非常正确,后一句是我加的,嘿嘿。
突击学习了下2者的却别,记录如下。
OC中可变对象和不可对象经常用的如下:
NSString, NSMutableString,| NSArray,NSMutableArray,
分开说:
A:NSString, NSMutableString
2者的copy方法返回类型为:
[NSString copy]               指针复制,返回的对象的地址和方法的接收者一样,引用计数加1
[NSMutableString copy]        深复制,重新Alloc一个 NSString 的对象,并返回。返回对象的地址和方法接收者的地址不一样,并且方法接受者的内容改变不影响返回对象,同时返回对象的内容不可以改变。

在这再说一下NSString 的copy 和retian。看到上面[NSString copy] 的解释和retain的使用没区别,为啥还需要2个,当时迷糊了下,分析后发下还是不一样的。
@property mString;
1:如果mString set 时为一个NSMutableString
   copy 属性,当set的对象内容修改时,不影响mString
   retian 属性,当set的对象内容修改时,mString的内容发生变化。
2:如果mString set时的对象为NSString
    不论是copy属性还是retain属性,因为set时对象为NSString,内容可能发生变化,所以使用任何一种属性达到的结果是一致的。
所以NSString在选择用retain 还是 copy 时,需要考虑到set的对象如果内容发生变化,需不需要影响到自己,如需则retain,如不需则copy。但是建议还是最好都是用copy,这样逻辑清晰,便于问题查找。
2者的MutableCopy方法返回的类型为:
[NSString mutableCopy]        深复制,重新Alloc一个NSMuatbleString,并返回。返回对象的地址和方法接收者的地址不一样,2者的内容改变不影响另一者,同时返回对象的内容可以改变。
[NSMutableString mutableCopy]  深复制,重新Alloc一个NSMuatbleString,并返回。返回对象的地址和方法接收者的地址不一样,2者的内容改变不影响另一者,同时返回对象的内容可以改变。

B:  NSArray,NSMutableArray
2者的copy方法返回类型为:
[NSArray copy]         指针复制,返回的对象的地址和方法的接受者的地址一样,引用计数加1,同时array里面的对象的地址都是一样的
[NSMutableArray copy]  “false深复制” 重新Alloc一个 NSArray对象,并返回,返回对象的地址和方法接收者的地址不一样,并且方法接受者本身内容(曾、减等操作,非包含对象内容的变化)改变不影响返回对象,同时返回对象的内容不可以改变。同时array里面的对象的地址都是一样的。
比如:
NSArray  *srcArray = [ NSArray   arrayWithObjects :[ NSMutableString   stringWithString : @"a" ], @"b" , @"c" , nil ];

NSMutableArray *arrMCopy = [srcArray mutableCopy];

NSArray        *arrCopy = [srcArray copy];

(lldb) p srcArray

(NSArray *) $2 = 0x0cf667c0 @"3 objects"

(lldb) p arrCopy

(NSArray *) $0 = 0x0cf667c0 @"3 objects"

(lldb) p arrMCopy

(NSMutableArray *) $1 = 0x0d077ab0 @"3 objects"

2者的MutableCopy方法返回的类型为:
[NSArray mutableCopy]          “false深复制” 重新Alloc一个NSMutableArray 并返回,返回对象的地址和方法接收者的地址不一样,并且2者的本身对象的增加,删除等操作不影响另一者。同时array里面的对象的地址都是一样的
[NSMutableArray mutableCopy]    同上。

NSMutableArray  *srcMArray = [ NSMutableArray   arrayWithObjects :[ NSMutableString   stringWithString : @"MArray" ], @"b" , @"c" , nil ];
NSMutableArray  *mArrMCopy = [srcMArray  mutableCopy ];
NSArray         *mArrayCopr = [srcMArray  copy ];

(lldb)p srcMArray 

(NSMutableArray *) $3 = 0x0ce70100 @"3 objects" 

(lldb) p mArrMCopy

(NSMutableArray *) $4 = 0x0cf667e0 @"3 objects" 

(lldb)p mArrayCopr

(NSArray *) $5 = 0x0cd82a50 @"3 objects”


再说下array里面的对象的问题。前面都提到,不论是NSArray还是NSMutableArray,他们的mutableCopy或者copy返回的对象里面所包含的对象的地址都是一样的,也就是说,里面包含的对象都是指针复制。我这里不能直观的打出array里对象的地址,可以做个测试。
NSString *srcObj1 = [arrCopy objectAtIndex : 0 ];

[srcObj1 appendString:@"IOS7"];

NSMutableString *srcObj2 = [arrCopyobjectAtIndex:0];

NSString *srcObj3 = [arrCopyobjectAtIndex:1];

(lldb)po srcArray

<__NSArrayI 0xce6fdc0>( aIOS7, sss, c )

(lldb)po arrCopy 

<__NSArrayI 0xce6fdc0>( aIOS7, sss, c )

(lldb)po arrMCopy 

<__NSArrayM 0xcf6e1e0>( aIOS7, sss, c

)
NSArray 的copy 返回的对象,只要修改其包含对象的的内容(前提是该对象可以修改),mutableCopy返回的对象里面的该对象内容也发生了变化。
再附上该对象的内存结构:

(lldb)p srcObj1 

(NSString *) $8 = 0x0cd92020 @"aIOS7" 

(lldb)p srcObj2

(NSMutableString *) $9 = 0x0cd92020 @“aIOS7"

(lldb)p *srcObj1

(NSString) $5 = {  NSObject = {    isa = __NSCFString  } } 

(lldb)p *srcObj2 

(NSMutableString) $6 = {  NSString = {    NSObject = {      isa = __NSCFString    }  } }

(lldb)p *srcObj3 

(NSString) $7 = {  NSObject = {    isa = __NSCFString  }

}

NSMutableArray 的copy 和mutableCopy可以自己证明下。
总结:
1:对于不可变对象,copy都是浅复制,即指针复制。mutableCopy 都是Alloc一个新对象返回。
2:对于可变对象,copy和mutableCopy都是Alloc新对象返回。
3:不论是可变还是不可变对象,copy返回的对象都是不可变的,mutableCopy返回的对象都是可变的。

4:容器类对象,不论是可变的还是不可变的,copy,mutableCopy返回的对象里所包含的对象的地址和之前都是一样 的,即容器内对象都是浅拷贝。

参考文章链接:

http://www.cnblogs.com/ydhliphonedev/archive/2012/04/27/2473927.html

http://www.tuicool.com/articles/yEreui%20

http://bjtumingfish.diandian.com/post/2013-03-18/40048120497%20

http://fanliugen.com/?p=278


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值