iOS 深拷贝和浅拷贝的区别
2019-03-19 本文已影响4人
来自蒙塔基的钢蛋儿
1.为什么是copy
一般来说,A copy 之后得到 copyA ,然后我们在修改copyA的值得时候 A 会跟着变化我们称作浅拷贝。
深拷贝就是 A copy 之后得到 copyA,在我们修改copyA的值的时候,两个实例不会相互影响.
2.copy
,mutableCopy
方法有什么区别?
所有继承于NSObject的class都声明了copy
和mutableCopy
方法,但是并没有实现NSCopying,NSMutableCopying
协议,所以Foundation框架中要使用copy
方法是要实现NSCopying,NSMutableCopying
协议的。
我们常用的就是NSString
,apple已经为NSString
实现了协议,block也可以调用copy
方法。
下面分析一下copy
和mutableCopy
方法:
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
NSString *str4 = [str1 mutableCopy];
(lldb) p str1
(__NSCFConstantString *) $1 = 0x0000000105981060 @"我是字符串"
(lldb) p str2
(__NSCFConstantString *) $2 = 0x0000000105981060 @"我是字符串"
(lldb) p str3
(__NSCFString *) $3 = 0x000060000007edc0 @"我是字符串"
(lldb) p str4
(__NSCFString *) $4 = 0x000060000007ef40 @"我是字符串"
这里需要解释一下,在runtime下NSString
的“真身”是__NSCFConstantString
而NSMutableString
的“真身”是__NSCFString
,然后我们就能很清楚的看到,只要是copy
得到的值就是不可变类型,而mutablecopy
得到的是可变类型。
2.容器类调用copy
和mutableCopy
方法:
NSMutableArray * arr = [NSMutableArray array];
//不可变容器
NSArray * copy_arr = [arr copy];
//与copy_arr完全相等
NSArray * new_copy_arr = [arr copy];
//返回一个可变数组,地址与原数组不一致
NSMutableArray * m_copy_arr = [arr mutableCopy];
由上可得出,容器类调用copy
会得到一个不可变的容器,而调用mutableCopy
会返回一个可变容器,不区分调用者。
这里无论深拷贝还是浅拷贝都是iOS中的称呼,结果容器内的数据其实都是不变的指针,改动当中元素的数据,都是跟着变得,因为只是容器地址发生改变,内容始终是一份,在JS当中可以利用JSON.parse
和JSON.stringify
得到一份新的数组。OC当中相对麻烦一些,
- 利用YYModel
- 容器内对象实现
Copying
协议,然后调用
- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;