又是一个老生常谈的话题,可是貌似这个问题,好多ios开发工程师并不能理解透彻,所以简单记录分析一下深复制与浅复制的原理以及strong,copy修饰符的原理和使用。
一、深复制与浅复制
1、区分深复制与浅复制其实很简单,最直观的一点就是是否创建了新的对象(或者说副本)。(这里说的是内容是否被copy)。浅复制只是引用计数加一,没有创建新的对象;深复制直接把内容复制,创建了新的对象。
2、不同情况下的copy和mutablecopy是否会创建新的对象
1》深拷贝:如果建立出新的副本,在内存中有两个对象.就是深拷贝.
可变 -> 不可变 (copy)
可变 -> 可变 (mutableCopy)
不可变 -> 可变 (mutableCopy)
2》浅拷贝:不会建立新的副本, 只是引用计数加1.
不可变 -> 不可变 (因为两个不可变对象谁都不会被改变,也就没必要建立副本)
小结:[object1 doCopy] objec1 和 docopy 有一个是带mutable的就会产生新的对象(docopy指的是copy或者
mutablecopy)
二、strong,copy修饰符的区别
这个有点老生常谈了,很简单的一个问题
copy修饰符:对 “=” 右边的对象先release,然后copy一份赋值给“=”左边的对象。
strong修饰符:对 “=” 右边的对象先release,然后直接retain,引用计数加一,赋值给“=”左边的对象。
举例说明:
//cMArr 是由copy修饰的,所以在赋值时其实是把[mmArr mutableCopy] 执行copy之后的结果赋值给了cMArr,这时结果其实是一个NSArray类型(可变数组copy之后生成新对象,新对象为不可变数组)
//sMArr 是由strong修饰,赋值时相当于是对右边的对象先release再retain,直接引用计数加一,并没有创造新的对象,所以sMArr 和mmArr指向同一内存区
@property(copy,nonatomic) NSMutableArray *cMArr;
@property(strong,nonatomic) NSMutableArray *sMArr;
NSMutableArray *mmArr = [@[@"111",@"222"] mutableCopy];
self.cMArr = [mmArr mutableCopy];
self.sMArr = mmArr;
NSLog(@"\nmmArr = %p %@, \ncmArr = %p %@,\nsmArr = %p %@",mmArr,[mmArr class],self.cMArr,[self.cMArr class],self.sMArr,[self.sMArr class]);
三、copy,strong修饰符使用习惯
1》copy修饰不可变类型,这样赋值的时候每次都要对右边的对象copy一次,确保内容的独立性。
2》strong修饰可变类型,赋值时直接对等号右边进行引用计数加一,当然等号右边要是不可变类型,代码mutablecopy之后再赋值。
3》strong修饰不可变类型,如果等号右边是可变类型会出现赋值之后等号左边内容是可变类型的情况,当然可以赋值前代码copy一下避免这个问题(慎用,谨防忘记代码copy然后才能赋值)
4》copy修饰可变类型,每次赋值都对等号右边进行一次copy,最终结果只能是不可变类型(禁用)
另一篇博客中,具体分析了一个特例数组的各种情况,点击这里查看