iOS - 深拷贝、浅拷贝探索验证

简介: 本文已同步掘金:iOS - 深拷贝、浅拷贝探索验证

1. 概念


浅拷贝:拷贝后,并没有进行真正的复制,拷贝后对象和原对象指向同一个地址

深拷贝:拷贝后对象指向了新的地址


2. 非集合类对象


1. 非集合类不可变对象

NSString *str1 = @"hello world";
    NSString *str2 = [str1 copy];
    NSString *str3 = [str1 mutableCopy];
    NSLog(@"\n str1 = %p class = %@", str1, str1.class);
    NSLog(@"\n str2 = %p class = %@", str2, str2.class);
    NSLog(@"\n str3 = %p class = %@", str3, str3.class);


输出

2021-05-08 17:09:47.697211+0800 AlgorithmDemo[33483:14523594] 
 str1 = 0x100008220 class = __NSCFConstantString
 str2 = 0x100008220 class = __NSCFConstantString
 str3 = 0x10044f8d0 class = __NSCFString


由打印可得:


  • 对于非集合类不可变对象的copy为浅拷贝,mutableCopy为深拷贝


  • 浅拷贝获得的对象与原对象地址一致,返回的对象为不可变对象(其实就是原对象)


  • 深拷贝返回新的内存地址,返回的对象为可变对象


2. 非集合类可变对象

NSString *str1 = [NSMutableString stringWithString:@"hello world"];
    NSMutableString *str2 = [str1 copy];
    NSMutableString *str3 = [str1 mutableCopy];
    NSLog(@"\n str1 = %p class = %@", str1, str1.class);
    NSLog(@"\n str2 = %p class = %@", str2, str2.class);
    NSLog(@"\n str3 = %p class = %@", str3, str3.class);


输出

2021-05-08 17:10:45.047818+0800 AlgorithmDemo[33588:14525427] 
 str1 = 0x1029045f0 class = __NSCFString
 str2 = 0x102904640 class = __NSCFString
 str3 = 0x102904760 class = __NSCFString


由打印可得


  • 非集合类可变对象copy是深拷贝


  • 非集合类可变对象mutableCopy是深拷贝


  • copy和mutableCopy返回的对象都是可变对象


3. 集合类对象


集合类不可变对象

NSString *str1 = @"hello world";
    NSMutableString *str2 = [NSMutableString stringWithString:@"hello world"];
    NSArray *array1 = [NSArray arrayWithObjects: str1, str2, nil];
    NSArray *array2 = [array1 copy];
    NSArray *array3 = [array1 mutableCopy];
    NSLog(@"\n array1 = %p class = %@ \n", array1, [array1 class]);
    NSLog(@"\n array2 = %p class = %@ \n", array2, [array2 class]);
    NSLog(@"\n array3 = %p class = %@ \n", array3, [array3 class]);
    NSLog(@"\n\n======== 元素是String ======== ");
    NSLog(@"\n obj0 = %p class = %@ \n", array1[0], [array1[0] class]);
    NSLog(@"\n obj0 = %p class = %@ \n", array2[0], [array2[0] class]);
    NSLog(@"\n obj0 = %p class = %@ \n", array3[0], [array3[0] class]);
    NSLog(@"\n\n======== 元素是mutableString ========");
    NSLog(@"\n obj1 = %p class = %@ \n", array1[1], [array1[1] class]);
    NSLog(@"\n obj1 = %p class = %@ \n", array2[1], [array2[1] class]);
    NSLog(@"\n obj1 = %p class = %@ \n", array3[1], [array3[1] class]);


输出

2021-05-08 17:34:32.740896+0800 AlgorithmDemo[39309:14557776] 
 array1 = 0x102904180 class = __NSArrayI
 array2 = 0x102904180 class = __NSArrayI
 array3 = 0x102904260 class = __NSArrayM
======== 元素是String ======== 
 obj0 = 0x100008220 class = __NSCFConstantString
 obj0 = 0x100008220 class = __NSCFConstantString
 obj0 = 0x100008220 class = __NSCFConstantString
======== 元素是mutableString ========
 obj1 = 0x1028719b0 class = __NSCFString
 obj1 = 0x1028719b0 class = __NSCFString
 obj1 = 0x1028719b0 class = __NSCFString


由打印可得:


  • 集合类不可变对象的copy为浅拷贝


  • mutableCopy为深拷贝


  • 无论copy还是mutableCopy集合内元素都是浅拷贝


集合类可变对象

NSString *str1 = @"hello world";
    NSMutableString *str2 = [NSMutableString stringWithString:@"hello world"];
    NSMutableArray *array1 = [NSMutableArray arrayWithObjects: str1, str2, nil];
    NSMutableArray *array2 = [array1 copy];
    NSMutableArray *array3 = [array1 mutableCopy];
    NSLog(@"\n array1 = %p class = %@ \n", array1, [array1 class]);
    NSLog(@"\n array2 = %p class = %@ \n", array2, [array2 class]);
    NSLog(@"\n array3 = %p class = %@ \n", array3, [array3 class]);
    NSLog(@"\n\n======== 元素是mutableString ========");
    NSLog(@"\n obj0 = %p class = %@ \n", array1[0], [array1[0] class]);
    NSLog(@"\n obj0 = %p class = %@ \n", array2[0], [array2[0] class]);
    NSLog(@"\n obj0 = %p class = %@ \n", array3[0], [array3[0] class]);
    NSLog(@"\n\n======== 元素是String ======== ");
    NSLog(@"\n obj1 = %p class = %@ \n", array1[1], [array1[1] class]);
    NSLog(@"\n obj1 = %p class = %@ \n", array2[1], [array2[1] class]);
    NSLog(@"\n obj1 = %p class = %@ \n", array3[1], [array3[1] class]);


输出:

2021-05-08 17:40:01.757406+0800 AlgorithmDemo[40202:14563979] 
 array1 = 0x1006046e0 class = __NSArrayM
 array2 = 0x100604860 class = __NSArrayI
 array3 = 0x100604890 class = __NSArrayM
======== 元素是mutableString ========
 obj0 = 0x100008220 class = __NSCFConstantString
 obj0 = 0x100008220 class = __NSCFConstantString
 obj0 = 0x100008220 class = __NSCFConstantString
======== 元素是String ======== 
 obj1 = 0x100604510 class = __NSCFString
 obj1 = 0x100604510 class = __NSCFString
 obj1 = 0x100604510 class = __NSCFString


结论:


集合类可变对象的mutableCopy和copy都是深拷贝,但集合内元素是浅拷贝


总结


列个表看看


非集合类


_ copy mutableCopy
NSString 浅拷贝返回原对象 深拷贝返回新的NSString
NSMutableString 深拷贝返回新NSMutableString 深拷贝返回新NSMutableString


一句话总结:非集合类对象只有不可变对象的copy是浅拷贝,其它都是深拷贝
集合类


_ copy mutableCopy
NSArray 浅拷贝元素浅拷贝 深拷贝元素浅拷贝
NSMutableArray 深拷贝元素浅拷贝 深拷贝元素浅拷贝


一句话总结:集合类对象只有不可变对象的copy是浅拷贝,其它都是深拷贝,且集合内元素都是浅拷贝


也可换个方式总结:


  • copy:对不可变对象是浅拷贝,可变对象是深拷贝


  • mutableCopy:始终是深拷贝


  • 无论深浅拷贝,集合对象内元素都是浅拷贝


相关文章
|
数据安全/隐私保护 Android开发 iOS开发
解决第三方邮箱APP登陆QQ、163邮箱无法验证账户名或密码的问题(IOS、MacOS、Windows、Android)
解决第三方邮箱APP登陆QQ、163邮箱无法验证账户名或密码的问题(IOS、MacOS、Windows、Android)
217 0
|
开发者 iOS开发
iOS开发 - 用AFNetworking实现https单向验证,双向验证
iOS开发 - 用AFNetworking实现https单向验证,双向验证
424 0
iOS开发 - 用AFNetworking实现https单向验证,双向验证
|
iOS开发
iOS开发-https免证书验证
iOS开发-https免证书验证
169 0
|
iOS开发
IOS最严格身份证号验证
IOS最严格身份证号验证
145 0
|
iOS开发
iOS自动化真机测试验证环境过程中常见问题解析
iOS自动化真机测试验证环境过程中常见问题解析
iOS自动化真机测试验证环境过程中常见问题解析
本章节主要讲解 iOS 自动化真机配置以及在 iOS 真机执行自动化时常见问题与解决方法。 ## 真机使用的Capability 与模拟器不同,真机测试需要如下的 Capability 方式一:设置 App 路径,启动 App(自动安装 App) ``` { "app": "/Users/seveniruby/Library/Developer/Xcode/DerivedData/UI
|
架构师 iOS开发
iOS自动化真机测试验证环境过程中常见问题解析
本章节主要讲解 iOS 自动化真机配置以及在 iOS 真机执行自动化时常见问题与解决方法。 ## 真机使用的Capability 与模拟器不同,真机测试需要如下的 Capability 方式一:设置 App 路径,启动 App(自动安装 App) ``` { "app": "/Users/seveniruby/Library/Developer/Xcode/DerivedData/UI
|
iOS开发
iOS - 如何深拷贝Array内元素、自定义对象、及自定义对象的属性(下)
关于深拷贝、浅拷贝,请看上篇iOS - 深拷贝、浅拷贝探索验证
|
API iOS开发
iOS - 如何深拷贝Array内元素、自定义对象、及自定义对象的属性(上)
关于深拷贝、浅拷贝,请看上篇iOS - 深拷贝、浅拷贝探索验证
|
传感器 安全 生物认证
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
262 0
iOS传感器开发——为APP添加手机密码、指纹进行安全验证