浅拷贝/深拷贝

本文详细介绍了Objective-C中的深拷贝和浅拷贝的概念,通过实例展示了NSString、NSMutableString以及自定义类在深拷贝和浅拷贝下的行为。对于非容器类对象,如NSString,copy是浅拷贝,mutableCopy是深拷贝。而对于可变对象,如NSMutableString,无论copy还是mutableCopy都是深拷贝。在自定义类中,正确实现copyWithZone和mutableCopyWithZone方法至关重要。对于容器对象,如NSArray和NSMutableArray,copy是浅拷贝,mutableCopy是深拷贝,但其内部元素始终进行指针复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浅拷贝是指针拷贝,2个指针(地址捆绑线)指向同一个地址堆内存区(同一个实例对象区)。
深拷贝是内容拷贝,深拷贝的过程中开辟全新的地址堆内存区存放内容副本,新的变量名指针(地址捆绑线)指向新开辟的地址堆内存副本区,最终2个变量名指针(地址捆绑线)指向2个不同的地址堆内存区。


深拷贝就是拷贝出和原来仅仅是值一样,但是内存地址完全不一样的新的对象,创建后和原对象没有任何关系。浅拷贝就是拷贝指向原来对象的指针,使原对象的引用计数+1,可以理解为创建了一个指向原对象的新指针而已,并没有创建一个全新的对象。

(1)非容器类对象的深拷贝、浅拷贝

// 字符串是直接赋值的,右侧如果是copy,那么就是浅拷贝;右侧如果是mutableCopy,那么就是深拷贝。
NSString *string1 = @“helloworld”;
NSString *string2 = [string1 copy]; // 浅拷贝
NSString *string3 = [string1 mutableCopy]; // 深拷贝
NSMutableString *string4 = [string1 copy]; // 浅拷贝
NSMutableString *string5 = [string1 mutableCopy]; // 深拷贝

NSLog(@"string1 = %d;string2 = %d",string1,string2);
NSLog(@"string1 = %d;string3 = %d",string1,string3);
NSLog(@"string1 = %d;string4 = %d",string1,string4);
NSLog(@"string1 = %d;string5 = %d",string1,string5);

打印结果如下:

  我这里用%d格式化打印出字符串对象的内存地址。我这里主要通过内存地址来判断是深拷贝还是浅拷贝,在该案例中,无论是深拷贝还是浅拷贝,字符串对象的值都是一样的,所以暂且就不打印值了,而只打印地址。这里的原字符串是直接赋值的,可以发现,右侧如果使用copy,那么打印出的内存地址是一样的,表示是浅拷贝,只拷贝出了指向原对象的指针,没有创建出新的对象。如果右侧使用mutableCopy,那么打印出的不一样的内存地址,表示创建了一个新的对象,是深拷贝。

 简单说明一下什么是非容器类对象,像NSString,NSNumber这些不能包含其他对象的叫做非容器类。如NSArray和NSDictionary可以容纳其他对象的叫做容器类对象。

做一个小小的总结:

– 浅拷贝类似retain,引用计数对象+1.创建一个指针;

– 深拷贝是真正意义上的拷贝,是创建一个新对象。copy属性表示两个对象内容相同,新的对象retain为1,与原对象的引用计数无关,原对象没有改变。copy减少对象对上下文的依赖。

– retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1.也就是说,retain是指针拷贝,copy是内容拷贝。

(2)改变字符串的创建方式,使用stringWithFormat创建字符串,而不是直接赋值

// 结果同上。右侧如果是copy,那么就是浅拷贝;右侧如果是mutableCopy,那么就是深拷贝。
NSString *string1 = [NSString stringWithFormat:@“helloworld”];
NSString *string2 = [string1 copy]; // 浅拷贝
NSString *string3 = [string1 mutableCopy]; // 深拷贝
NSMutableString *string4 = [string1 copy]; // 浅拷贝
NSMutableString *string5 = [string1 mutableCopy]; // 深拷贝

NSLog(@
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HaiJunYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值