iOS深拷贝与浅拷贝、NSString内存分配

简介:

copy与retain的区别

         1)copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。

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


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#pragma mark - iOS系统的集合类与非集合类的retain和copy
         // 非容器类(NSString / NSNumber等)
         NSString *str1 = [[NSString alloc] initWithFormat:@ "%@" , @ "Jacedy" ];
         NSString *str11 = [str1 retain];
         NSString *str12 = [str1 copy];
         NSString *str13 = [str1 mutableCopy];
         
         NSMutableString *str2 = [[NSMutableString alloc] initWithString:@ "Jake" ];
         NSMutableString *str21 = [str2 retain];
         NSMutableString *str22 = [str2 copy];
         NSMutableString *str23 = [str2 mutableCopy];
         
         NSLog(@ "非容器类" );
         NSLog(@ "str1 的地址:%p,retainCount:%lu" , str1, (unsigned  long )[str1 retainCount]);
         NSLog(@ "str11的地址:%p,retainCount:%lu" , str11, (unsigned  long )[str11 retainCount]);
         NSLog(@ "str12的地址:%p,retainCount:%lu" , str12, (unsigned  long )[str12 retainCount]);
         NSLog(@ "str13的地址:%p,retainCount:%lu\n\n" , str13, (unsigned  long )[str13 retainCount]);
         NSLog(@ "str2 的地址:%p,retainCount:%lu" , str2, (unsigned  long )[str2 retainCount]);
         NSLog(@ "str21的地址:%p,retainCount:%lu" , str21, (unsigned  long )[str21 retainCount]);
         NSLog(@ "str22的地址:%p,retainCount:%lu" , str22, (unsigned  long )[str22 retainCount]);
         NSLog(@ "str23的地址:%p,retainCount:%lu\n\n" , str23, (unsigned  long )[str23 retainCount]);
         
         // 容器类(集合类)(NSArray / NSSet等)
         NSArray *arr1 = [NSArray arrayWithObjects:@ "one" , @ "two" , nil];
         NSArray *arr11 = [arr1 retain];
         NSArray *arr12 = [arr1 copy];
         NSArray *arr13 = [arr1 mutableCopy];
         
         NSMutableArray *arr2 = [NSMutableArray arrayWithObjects:@ "one" , @ "two" , nil];
         NSMutableArray *arr21 = [arr2 retain];
         NSMutableArray *arr22 = [arr2 copy];
         NSMutableArray *arr23 = [arr2 mutableCopy];
         
         NSLog(@ "容器类" );
         NSLog(@ "arr1 的地址:%p,retainCount:%lu" , arr1, (unsigned  long )[arr1 retainCount]);
         NSLog(@ "arr11的地址:%p,retainCount:%lu" , arr11, (unsigned  long )[arr11 retainCount]);
         NSLog(@ "arr12的地址:%p,retainCount:%lu" , arr12, (unsigned  long )[arr12 retainCount]);
         NSLog(@ "arr13的地址:%p,retainCount:%lu" , arr13, (unsigned  long )[arr13 retainCount]);
         NSLog(@ "arr1[0] :%p" , arr1[0]);
         NSLog(@ "arr13[0]:%p\n\n" , arr13[0]);
         
         NSLog(@ "arr2 的地址:%p,retainCount:%lu" , arr2, (unsigned  long )[arr2 retainCount]);
         NSLog(@ "arr21的地址:%p,retainCount:%lu" , arr21, (unsigned  long )[arr21 retainCount]);
         NSLog(@ "arr22的地址:%p,retainCount:%lu" , arr22, (unsigned  long )[arr22 retainCount]);
         NSLog(@ "arr23的地址:%p,retainCount:%lu" , arr23, (unsigned  long )[arr23 retainCount]);
         NSLog(@ "arr2[0] :%p" , arr2[0]);
         NSLog(@ "arr22[0]:%p\n\n" , arr22[0]);
         
#pragma mark - NSString 内存管理
         
         NSString *string1 = @ "Jacedy" ;
         NSString *string2 = [[NSString alloc] initWithString:@ "KJacedy" ];
         NSString *string3 = [[NSString alloc] initWithFormat:@ "Jacedy" ];
         NSString *string4 = [NSString stringWithFormat:@ "K-Jacedy" ];
         //NSString *string5 = [NSString stringWithString:@"Jacedy"];    //该方法等同于string1
         NSLog(@ "NSString内存管理" );
         NSLog(@ "string1:%p retainCount:%lu  class:%@" , string1, [string1 retainCount], [string1  class ]);
         NSLog(@ "string2:%p retainCount:%lu  class:%@" , string2, [string2 retainCount], [string2  class ]);
         NSLog(@ "string3:%p retainCount:%lu  class:%@" , string3, [string3 retainCount], [string3  class ]);
         NSLog(@ "string4:%p retainCount:%lu  class:%@\n\n" , string4, [string4 retainCount], [string4  class ]);
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 输出结果:
 
非容器类
str1 的地址:0x79646563614a65,retainCount:18446744073709551615
str11的地址:0x79646563614a65,retainCount:18446744073709551615
str12的地址:0x79646563614a65,retainCount:18446744073709551615
str13的地址:0x100203a70,retainCount:1
 
str2 的地址:0x100203f20,retainCount:2
str21的地址:0x100203f20,retainCount:2
str22的地址:0x656b614a45,retainCount:18446744073709551615
str23的地址:0x100204040,retainCount:1
 
容器类
arr1 的地址:0x100300a90,retainCount:3
arr11的地址:0x100300a90,retainCount:3
arr12的地址:0x100300a90,retainCount:3
arr13的地址:0x100301190,retainCount:1
arr1[0] :0x1000021b0
arr13[0]:0x1000021b0
 
arr2 的地址:0x100301260,retainCount:2
arr21的地址:0x100301260,retainCount:2
arr22的地址:0x100301370,retainCount:1
arr23的地址:0x100301390,retainCount:1
arr2[0] :0x1000021b0
arr22[0]:0x1000021b0
 
NSString内存管理
string1:0x100002050 retainCount:18446744073709551615   class :__NSCFConstantString
string2:0x100002390 retainCount:18446744073709551615   class :__NSCFConstantString
string3:0x79646563614a65 retainCount:18446744073709551615   class :NSTaggedPointerString
string4:0xd2eec83802a585 retainCount:18446744073709551615   class :NSTaggedPointerString
 
Program ended with  exit  code: 0

深拷贝与浅拷贝结论

         1)对非集合类:

         [immutableObject copy] // 浅复制

         [immutableObject mutableCopy] //深复制

         [mutableObject copy] //深复制

         [mutableObject mutableCopy] //深复制

         

         2)对集合类:

         [immutableObject copy] // 浅复制

         [immutableObject mutableCopy] //单层深复制(即仅对对象本身进行深复制,对象元素仍是浅复制(指针拷贝,内存地址不变))

         [mutableObject copy] //单层深复制

         [mutableObject mutableCopy] //单层深复制

         

NSString内存分配结论

         @“” 和 initWithString:方法生成的字符串分配在常量区,系统自动管理内存;

         initWithFormat:和 stringWithFormat: 方法生成的字符串分配在堆区,autorelease


目录
相关文章
|
iOS开发 异构计算
如何增加 iOS APP 虚拟地址空间及内存上限?XNU 内核源码解读
1. 引言 最近一段时间在做钉钉 iOS 内存专项治理,解决内存不足时的 jetsam 事件及 malloc 的异常崩溃。在进程创建时系统会为每个 app 设定内存最大使用上限,内核会维护一个内存阈值优先级列表,当设备内存不足时低优先级的 app 会首先被内核中止进程。在阅读 XNU 内核源码过程中我们发现提供系统了两种能力可以扩展 App 的虚拟地址空间(com.apple.developer.kernel.extended-virtual-addressing)和增加内存使用上限(com.apple.developer.kernel.increased-memory-limit)。
1445 0
如何增加 iOS APP 虚拟地址空间及内存上限?XNU 内核源码解读
|
存储 算法 Java
iOS开发 - 穿针引线之内存管理(二)
iOS开发 - 穿针引线之内存管理
193 0
|
存储 程序员 C语言
iOS开发 - 穿针引线之内存管理(一)
iOS开发 - 穿针引线之内存管理
159 0
|
存储 算法 iOS开发
|
JavaScript 前端开发 Java
前端面试题【js动态创建节点、怎么阻止冒泡事件、怎么阻止默认事件、什么是深拷贝,什么是浅拷贝、js造成内存泄漏的操作有哪些等】
前端面试题【js动态创建节点、怎么阻止冒泡事件、怎么阻止默认事件、什么是深拷贝,什么是浅拷贝、js造成内存泄漏的操作有哪些等】
180 0
前端面试题【js动态创建节点、怎么阻止冒泡事件、怎么阻止默认事件、什么是深拷贝,什么是浅拷贝、js造成内存泄漏的操作有哪些等】
|
存储 监控 Unix
iOS-底层原理36:内存优化(一) 野指针探测
iOS-底层原理36:内存优化(一) 野指针探测
573 0
iOS-底层原理36:内存优化(一) 野指针探测
|
存储 安全 API
iOS-底层原理 33:内存管理(三)AutoReleasePool & NSRunLoop 底层分析
iOS-底层原理 33:内存管理(三)AutoReleasePool & NSRunLoop 底层分析
182 0
iOS-底层原理 33:内存管理(三)AutoReleasePool & NSRunLoop 底层分析
|
iOS开发
iOS-底层原理 33:内存管理(二)强引用分析
iOS-底层原理 33:内存管理(二)强引用分析
167 0
iOS-底层原理 33:内存管理(二)强引用分析
|
存储 编译器 Serverless
iOS-底层原理 33:内存管理(一)TaggedPointer/retain/release/dealloc/retainCount 底层分析
iOS-底层原理 33:内存管理(一)TaggedPointer/retain/release/dealloc/retainCount 底层分析
193 0
iOS-底层原理 33:内存管理(一)TaggedPointer/retain/release/dealloc/retainCount 底层分析
|
存储 安全 程序员
iOS-底层原理 24:内存五大区
iOS-底层原理 24:内存五大区
128 0
iOS-底层原理 24:内存五大区

热门文章

最新文章