copy与retain /深拷贝与浅拷贝

copy与retain的区别:

1.copy是创建一个新对象,retain是创建一个指针,引用对象计数加1.copy属性表示两个对象内容相同,新的对象retain为1,与旧有对象的引用计数无关,旧有对象没有变化copy减少对象上下文的依赖.

2.retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容当然是相同,这个对象的retain值加1,也就是说,retain是指针拷贝,copy是内容拷贝.

 

字符串为什么使用copy?

1.概念:

     假如有一个NSMutableString,现在用他给一个retain修饰的NSString赋值,那么只是将NSString指向了一个NSMutableString所指向的位置,并对NSMutableString奇数器加1,此时,

此时,如果对NSMutableString进行修改,也会导致NSString的值修改,原则上这是不允许的.

如果是copy修饰的NSString对象,在用NSMutableString给他赋值时,会进行深拷贝,及把内容也给拷贝了一份,两者指向不同位置,即使改变了NSMutableString的值,

NSString的值也不会改变.所以用copy是为了安全,防止NSMutableString赋值给NSString时,前者修改引起后者值变化而用的.

 

 2 提示 : 谨记Copy属性的setter方法的结构.

3 :简述,当给一个对象赋新值时,会把新值拷贝一个副本出来赋值给对象,这样新值跟旧值就没有任何关系.

 

 

浅拷贝和深拷贝

深拷贝:内容拷贝,源对象和副本对象指的是两个不同的对象,源对象引用计数器不变,副本引用计数器为1.

浅拷贝:指针拷贝,源对象和副本对象指的是同一个对象,对象引用计数器加1,相当于retain.

提示:只有不可变的对象创建不可变副本(copy)才是浅拷贝,其它都是深拷贝.

 

如果对不可变对象拷贝,copy是指针拷贝(浅拷贝);但是,mutableCopy就是对象拷贝(深拷贝).

如果是对可变对象拷贝,copy都是深拷贝,但是,copy返回的对象是不可变的.

 

 

 

自定义对象的拷贝

 

自定义对象如果要浅拷贝就遵守<NSCopying>协议  (copy)

自定义对象如果要深拷贝就遵守<NSMutableCopying>协议  (mutableCopy)

自定义对象遵守了相关协议,就能够调用相应的深拷贝或者浅拷贝的方法

 

当然在ios中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying 协议的类可以发送copy消息,遵守NSMutableCopying 协议的类才可以发送mutableCopy消息。假如发送了一个没有遵守上诉两协议而发送 copy或者 mutableCopy,那么就会发生异常。但是默认的ios类并没有遵守这两个协议。如果想自定义一下copy 那么就必须遵守NSCopying,并且实现 copyWithZone: 方法,如果想自定义一下mutableCopy 那么就必须遵守NSMutableCopying,并且实现 mutableCopyWithZone: 方法。

 

 

Block定义成属性为什么用Copy?

 MRC:block的本质是函数指针,内存地址在栈区,使用copy是为了把block由栈区拷贝到堆区,共享给当前对象使用.

ARC:block定义属性是,使用strong和copy效果一样,但是苹果官方建议使用copy.

 

 

容器的内存管理

[tmpM addObject:obj];

 这样obj的引用计数会增加1.tmpM对obj强引用.

 

  [tmpM removeObjectAtIndex:0];

  obj的引用计数会减1.tmpM不再对obj有引用.

 

posted @ 2017-03-03 13:46  Niki~  Views(289)  Comments(0Edit  收藏  举报