深拷贝 浅拷贝
浅拷贝
浅拷贝并不是拷贝对象本身,而是对指向对象的指针进行拷贝,但还是指向同一块堆内存中指针指向的对象
可以看出浅拷贝中栈内存中指针对象的地址改变了,但还是指向相同的一块堆内存地址
深拷贝
直接拷贝对象到内存中的一块区域,然后把新对象的指针指向这块内存。
可以看出深拷贝是直接拷贝对象到内存中的一块区域(分配了一块新的内存空间),然后把新对象的指针指向这块内存,原对象和被赋值对象互不影响。
深拷贝与浅拷贝的本质区别
在于是否在堆内存中开辟新的内存空间。
区分深拷贝与浅拷贝
主要从 容器类和 非容器 类着手,不管是容器类还是非容器类都有可变对象和不可变对象,所以分为四种:
- 非容器类不可变对象:NSString
- 非容器类可变对象:NSMutableString
- 容器类不可变对象:NSArray
- 容器类可变对象:NSMutableArray
结论
[object copy]:对于可变对象为深拷贝,不可变对象为浅拷贝。
[object mutableCopy]:始终都是深拷贝。
测试代码
// 对不可变对象 copy 为浅拷贝
{
NSString *objc = @"111";
NSString *objc1 = [objc copy];
NSString *objc2 = [objc mutableCopy];
NSLog(@"不可变对象copy为浅拷贝");
NSLog(@"堆内存地址%p - %p", objc, &objc);
NSLog(@"copy堆内存地址%p - %p", objc1, &objc1);
NSLog(@"mutalCopy为深拷贝");
NSLog(@"mutableCopy堆内存地址%p - %p", objc2, &objc2);
NSLog(@"====================");
}
{
NSArray *objc = @[@1];
NSArray *objc1 = [objc copy];
NSArray *objc2 = [objc mutableCopy];
}
// 可变对象 copy 为深拷贝
{
NSMutableString *objc = [[NSMutableString alloc] initWithString:@"111"];
NSString *objc1 = [objc copy];
NSString *objc2 = [objc mutableCopy];
NSLog(@"可变对象copy、muatalCopy都是深拷贝");
NSLog(@"堆内存地址%p - %p", objc, &objc);
NSLog(@"copy堆内存地址%p - %p", objc1, &objc1);
NSLog(@"mutableCopy堆内存地址%p - %p", objc2, &objc2);
NSLog(@"====================");
}
{
NSMutableArray *objc = [NSMutableArray arrayWithArray:@[@1]];
NSArray *objc1 = [objc copy];
NSArray *objc2 = [objc mutableCopy];
}