在讨论深浅拷贝之前,先明确一下它们的含义
深拷贝:重新开辟一块内存区域,拷贝对象的内容,不影响对象的引用计数
浅拷贝:与之前的对象共用一块内存,仅拷贝对象的地址,对象的引用计数加1
对于strong修饰的对象,都是浅拷贝,仅拷贝对象的地址,使得对象的引用计数加1 ,而copy和mutableCopy主要分为集合类对象和非集合类对象来讨论,先给一张图。mutable:可变 immutable:不可变
上图总结如下:
- mutable对象(集合类与非集合类)的copy和mutableCopy都是深拷贝(包括集合类的不完全深拷贝)
- immutable对象的copy都是浅拷贝,mutableCopy是深拷贝
- copy返回的都是不可变对象
对于集合类对象,在深拷贝时即内容拷贝,拷贝的只是集合类的对象,对于其内部的元素依然是浅拷贝即指针拷贝
如何实现集合类对象深拷贝时,对其内部元素也实现深拷贝,方法如下:
- 使用集合类的如下生成方法
NSArray *array = [[NSArray alloc] initWithArray:otherArray copyItems:YES];
将copyItems:设置为YES即可实现内部元素的深拷贝,设置后集合中的每个对象都会收到copyWithZone:方法,如果对象遵循了NSCoping协议,集合中内部的对象就会被深拷贝到新的集合中;如果对象没有遵循这个协议,在复制时就会报错。
copyWithZone:
只能够提供一层内存拷贝,而不是真正的深拷贝
- 通过对集合对象进行归档再解档的方式实现内部元素的深拷贝
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:otherArray]];
为什么在声明不可变对象属性时用copy
为了保证当前属性对象不受外界影响
使用copy无论传的是可变还是不可变的对象
返回的都是一个不可变的对象,确保当前属性不会无意间变化
copy用来修饰不可变对象,以保护对象的封装性