iOS 深度理解浅拷贝与深拷贝

5 篇文章 0 订阅

在工作中如果不能正确理解浅拷贝与深拷贝就会造成不想改变的值被改变了,出现了再次使用数组时没有数据,显示的值不是我们想要的等一些问题。只有真正理解了浅拷贝与深拷贝才能使我们在开发中事半功倍,废话少说,代码走起~~~

定义理解

浅拷贝:拷贝后只是指向了该对象的地址,这两个对象指向了同一个内存地址,通过任何一个对象修改值,这两个对象再次获取值都是获取修改后的值。
深拷贝:拷贝了对象的内容然后重新开辟了新的内存空间,这是两个互相独立的对象,对任意一个修改值,另一个的值都不会改变。

字符串的深拷贝与浅拷贝

不可变字符串

NSString *test = @"copy456";
NSString *test1 = [test copy]; //浅拷贝
NSString *test2 = [test mutableCopy]; //深拷贝

打印结果:

 test:0x101683068
 test1:0x101683068
 test2:0x604000049330

从打印结果我们可以看到使用copy赋值给一个不可变对象时是浅拷贝,指向了同一个内存地址。使用mutableCopy赋值给一个不可变对象是深拷贝,重新分配了内存空间。

可变字符串

NSMutableString *mtest = [[NSMutableString alloc] initWithString:@"mutableCopy NSSting"];
NSMutableString *mtest4 = [mtest copy]; // 深拷贝
NSMutableString *mtest5 = [mtest mutableCopy]; //深拷贝

打印结果:

 mtest:0x600000445ac0
 mtest4:0x600000445c10
 mtest5:0x600000445a90

通过copy或mutableCopy的方式赋值给可变对象,从打印的结果可以看到它们三个指向的内存地址都是不一样的,因此都是深拷贝。

集合类对象的深拷贝与浅拷贝

对于集合类对象我们以数组为例进行说明

不可变对象

NSArray *testArray = @[@"A", @"B", @"C"];
NSArray *testArray1 = [testArray copy]; //浅拷贝
NSArray *testArray2 = [testArray mutableCopy]; //深拷贝

打印结果:

testArray:0x60400004a4d0
testArray1:0x60400004a4d0
testArray2:0x60400004a770

通过copy赋值testArray1与testArray指向相同的内存地址,因此通过copy的方式赋值给不可变对象是浅拷贝。testArray2是新的内存地址,通过mutableCopy的方式赋值给一个不可变对象是深拷贝。

可变对象

NSMutableArray *mTestArray = [[NSMutableArray alloc] init];
NSMutableArray *mTestArray1 = [mTestArray copy]; //深拷贝
NSMutableArray *mTestArray2 = [mTestArray mutableCopy]; //浅拷贝

打印结果:

testArray:0x60800005ba50
testArray1:0x60c000004910
testArray2:0x60800005bc00

无论是copy还是mutableCopy赋值给一个可变对象时都是深拷贝。

集合对象的值

打印数组的第一个值的内存地址

NSLog(@"testArray 1value:%p", [mTestArray objectAtIndex:0]);
NSLog(@"testArray1 1value:%p", [mTestArray1 objectAtIndex:0]);
NSLog(@"testArray2 1value:%p", [mTestArray2 objectAtIndex:0]);

打印结果:

 testArray 1value:0x104b67238
 testArray1 1value:0x104b67238
 testArray2 1value:0x104b67238

我们看到打印的结果第一个值都指向了同一个内存地址,这说明集合对象的深拷贝只是单层深拷贝,只是给该对象分配了一个新的内存地址而集合对象里面的值还都指向原来的内存地址。

property中使用copy属性

@interface ViewController ()

@property (nonatomic, copy) NSString *pTest;
@property (nonatomic, copy) NSMutableString *mpTest;

@end

self.pTest = test;
NSLog(@"test:%p", test);
NSLog(@"pTest:%p", _pTest);

self.mpTest = mtest;
NSLog(@"mtest:%p", mtest);
NSLog(@"mpTest:%p", _mpTest);

打印结果:

test:0x10b07e088
pTest:0x10b07e088
mtest:0x6040002410e0
mpTest:0x604000241770

通过打印结果我们可以看到不可变对象是浅拷贝,可变度对象是深拷贝。其实看到set方法的实现原来我们就明白了property里的copy什么时候是深拷贝,什么时候是浅拷贝

- (void)setPTest:(NSString *)pTest {
    _pTest = [pTest copy];
}

GitHub地址:https://github.com/jiamingzhou/Copy.git
简书地址:http://www.jianshu.com/u/eb0b5181f862

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值