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