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