谈谈数组的浅拷贝和深拷贝(copy & mutableCopy)

1、基本分析
1.1、数组有两种形式,NSArray和NSMutableArray;
1.2、拷贝也有两个方法copy和mutableCopy;
1.3、那么相互组合就会有四种情况:NSArray的copy、mutableCopy;NSMutableArray的copy、mutableCopy;

2、代码验证
2.1、先创建一个NSObject对象与一个NSArray数组,将对象放到数组中;
2.2、分别对NSArray数组进行copy与mutableCopy,查看得到的结果数据类型及地址

NSObject *object = [[NSObject alloc] init];
NSArray *array = [NSArray arrayWithObject:object];
NSArray *copy = [array copy];
NSArray *mutableCopy = [array mutableCopy];

Printing description of array: <__NSArrayI 0x7fa739e2ad90> ( <NSObject: 0x7fa739e09240>)
Printing description of copy: <__NSArrayI 0x7fa739e2ad90> ( <NSObject: 0x7fa739e09240>)
Printing description of mutableCopy: <__NSArrayM 0x7fa739e1aa00> ( <NSObject: 0x7fa739e09240>)

2.3、分别对NSMutableArray进行copy与mutableCopy,查看得到的结果数据类型及地址

NSObject *object = [[NSObject alloc] init];
NSMutableArray *mutableArray = [NSMutableArray arrayWithObject:object];
NSArray *copy = [mutableArray copy];
NSArray *mutableCopy = [mutableArray mutableCopy];

Printing description of mutableArray: <__NSArrayM 0x7f8a1af6ba70> ( <NSObject: 0x7f8a1af65970> )
Printing description of copy: <__NSArrayI 0x7f8a1af66650> ( <NSObject: 0x7f8a1af65970> )
Printing description of mutableCopy: <__NSArrayM 0x7f8a1af12150> ( <NSObject: 0x7f8a1af65970> )

3、结果分析:
3.1、对于NSArray来讲,原数组、copy、mutableCopy的结果对比:
NSArrayI? ?0x7fa739e2ad90
NSArrayI? ?0x7fa739e2ad90
NSArrayM 0x7fa739e1aa00
3.2、对于NSMutableArray来讲,原数组、copy、mutableCopy的结果对比:
NSArrayM 0x7f8a1af6ba70
NSArrayI?? 0x7f8a1af66650
NSArrayM 0x7f8a1af12150

3.3、得出以下结论:
A、copy得到的结果一定是NSArray类型,mutableCopy得到的一定是NSMutableArray类型;
B、NSArray的copy方法由于没有类型转换,得到的还是原数组,相当于赋值,没有创建新数组;
C、NSArray的mutableCopy方法得到了与原数组类型不同的可变数组,毋庸置疑创建了新数组;
D、NSMutableArray的copy方法参照A,得到的类型与原数组类型不同,毋庸置疑创建了新数组;
E、NSMutableArray的mutableCopy方法,得到的类型与原数组类型相同,但同样创建了新数组;
F、比较B与E,再参照A推断,E应该也只是赋值的效果,然而结果却不是,可能这就是mutableCopy所谓的深拷贝缘故吧!

3.4、仔细观察比较结果里面还一个特点,即无论何种拷贝,NSObject从头到尾都是没有变化的,也就是说,尽管数组本身开辟了新的存储空间,但数组中的元素却依旧还是不变的那些元素,站在元素本身的角度来看,只是多了几个指针指向了他而已;

3.5、如果在拷贝的时候希望连同数组内元素也拷贝一份则需要调用数组的另一个方法:
– (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;

3.6、数组中元素如果没有实现NSCoping协议,则还需要先实现该协议,否则拷贝会出错,系统自带的类如:NSString、NSArray、NSDictionay、NSNumber等已实现NSCoping协议。

Leave a Reply