数组拷贝

源于微信群里一个问题讨论,具体陈铭嘉博客总结的很详细:http://www.jianshu.com/p/9a2952c792e6

我主要是实践验证一下文章中的代码,其中Swift中的内存指针参看:http://onevcat.com/2015/01/swift-pointer/

Objective-C 部分:

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
//第一层理解:
//如果对一个不可变容器复制,copy是指针复制,即浅拷贝。
//如果对一个可变容器复制,copy是对象复制,即深拷贝。
NSArray *array = [NSArray array];
NSArray *array2 = [array copy];
NSLog(@"%p and %p", array, array2);

NSMutableArray *marray = [NSMutableArray array];
NSMutableArray *marray2 = [marray copy];
NSLog(@"%p and %p", marray, marray2);

// 第二层理解:
// 如果是对可变容器copy,是对象复制,即深拷贝,但拷贝出的是一个不可变容器。
// 如果是对可变容器mutableCopy才符合正确地copy语义,也是对象复制,即深拷贝,这次拷贝出的是一个可变容器。
NSMutableArray *array3 = [NSMutableArray array];
NSLog(@"%@", [array3 class]);
[array3 addObject:@"Panda"];

NSMutableArray *array4 = [array3 mutableCopy];
NSLog(@"%@", [array4 class]);
[array4 addObject:@"Lion"]; //成功

NSMutableArray *array5 = [array3 copy];
NSLog(@"%@", [array5 class]);
//[array5 addObject:@"Lion"]; //报错

// 第三层理解:
// 上述的深拷贝其实还不是完全深拷贝,因为第二层的图可以发现mutableCopy的数组仍然共享同样的数组元素。
// 而完全深拷贝即是对数组元素同样的拷贝的真正深拷贝。
NSMutableArray *marray3 = [NSMutableArray array];
[marray3 addObject:@"Panda"];
NSMutableArray *marray4 = [marray3 mutableCopy]; //一般深拷贝
[marray4 addObject:@"Li"];
NSMutableArray *marray5 = [NSKeyedUnarchiver
unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject:marray3]]; //完全深拷贝
NSLog(@"数组第一个元素的指针 -> 1:%p \n 2:%p \n 3:%p", marray3[0], marray4[0], marray5[0]);
NSLog(@"数组的指针 -> 1:%p \n 2:%p \n 3:%p", marray3, marray4, marray5);

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 0x7fd2e2501ff0 and 0x7fd2e2501ff0
0x7fd2e2500710 and 0x7fd2e2501ff0


__NSArrayM
__NSArrayM
__NSArrayI


数组第一个元素的指针 -> 1:0x10c0730a0
2:0x10c0730a0
3:0xa000061646e61505
数组的指针 -> 1:0x7fd2e260f7a0
2:0x7fd2e262c230
3:0x7fd2e260b6b0

Swift 部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//copy array swift
var array1 = [1, 2, 3, 4, 5]
var array4 = array1
var arrayPtr1 = UnsafeMutableBufferPointer<Int>(start: &array1, count: array1.count)
var arrayPtr4 = UnsafeMutableBufferPointer<Int>(start: &array4, count: array4.count)
print(array1)
print(array4)
print(arrayPtr1)
print(arrayPtr4)


array1[0] = 10
array1.append(20)
print(array1)
print(array4)
var arrayPtr7 = UnsafeMutableBufferPointer<Int>(start: &array1, count: array1.count)
var arrayPtr8 = UnsafeMutableBufferPointer<Int>(start: &array4, count: array4.count)
print(arrayPtr7)
print(arrayPtr8)

输出:

1
2
3
4
5
6
7
8
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
UnsafeMutableBufferPointer(start: 0x00007fb568da65f0, length: 5)
UnsafeMutableBufferPointer(start: 0x00007fb568da65a0, length: 5)
[10, 2, 3, 4, 5, 20]
[1, 2, 3, 4, 5]
UnsafeMutableBufferPointer(start: 0x00007fb568da65f0, length: 6)
UnsafeMutableBufferPointer(start: 0x00007fb568da65a0, length: 5)