iOS OC中copy和mutableCopy的使用区别
// 浅复制
- (IBAction)shallowCopyAction:(id)sender {
NSArray *array0 = @[@"A", @"B", @"C"];
NSArray *array1 = array0;
NSArray *array2 = [array0 copy];
NSLog(@"array0 = %@ 指针地址 = %p", array0, array0);
NSLog(@"array1 = %@ 指针地址 = %p", array1, array1);
NSLog(@"array2 = %@ 指针地址 = %p", array2, array2);
array0 = @[@"OK", @"YES", @"NO"];
NSLog(@"array0 = %@ 指针地址 = %p", array0, array0);
NSLog(@"array1 = %@ 指针地址 = %p", array1, array1);
NSLog(@"array2 = %@ 指针地址 = %p", array2, array2);
}
打印输出:
2020-04-02 21:12:06.775103+0800 CopyDemo[1158:20138] array0 = (
A,
B,
C
) 指针地址 = 0x600002880de0
2020-04-02 21:12:06.775339+0800 CopyDemo[1158:20138] array1 = (
A,
B,
C
) 指针地址 = 0x600002880de0
2020-04-02 21:12:06.775487+0800 CopyDemo[1158:20138] array2 = (
A,
B,
C
) 指针地址 = 0x600002880de0
2020-04-02 21:12:06.775605+0800 CopyDemo[1158:20138] array0 = (
OK,
YES,
NO
) 指针地址 = 0x600002880e70
2020-04-02 21:12:06.775713+0800 CopyDemo[1158:20138] array1 = (
A,
B,
C
) 指针地址 = 0x600002880de0
2020-04-02 21:12:06.775823+0800 CopyDemo[1158:20138] array2 = (
A,
B,
C
) 指针地址 = 0x600002880de0
分析:
我们可以看到,在array0赋值成@[@“OK”, @“YES”, @“NO”]之前,array0、array1和array2都指向同一块内存空间,内容自然也相同。
(1) array1 = array0,所以array1和array0指向同一块内存空间
(2) copy操作如果来源对象是否可变,如果来源对象是不可变对象(NSArray),则只拷贝指针,也就是浅拷贝;
array0赋值成@[@“OK”, @“YES”, @“NO”]之后:
(1) array0指向了新的一块内存空间,也就是@[@“OK”, @“YES”, @“NO”]的内存空间;
(2) 而array1和array2仍指向之前的一块内存空间,也就是@[@“A”, @“B”, @“C”]的内存空间,所以内容还是@[@“A”, @“B”, @“C”]
// 深复制
- (IBAction)deepCopyAction:(id)sender {
NSArray *array0 = @[@"A", @"B", @"C"];
NSMutableArray *array1 = [array0 mutableCopy];
NSMutableArray *array2 = array1;
NSMutableArray *array3 = [array1 mutableCopy];
NSLog(@"array0 = %@ 指针地址 = %p", array0, array0);
NSLog(@"array1 = %@ 指针地址 = %p", array1, array1);
NSLog(@"array2 = %@ 指针地址 = %p", array2, array2);
NSLog(@"array3 = %@ 指针地址 = %p", array3, array3);
array0 = @[@"OK", @"YES", @"NO"];
[array1 addObject:@"D"];
NSLog(@"array0 = %@ 指针地址 = %p", array0, array0);
NSLog(@"array1 = %@ 指针地址 = %p", array1, array1);
NSLog(@"array2 = %@ 指针地址 = %p", array2, array2);
NSLog(@"array3 = %@ 指针地址 = %p", array3, array3);
}
打印输出:
2020-04-02 21:17:57.474876+0800 CopyDemo[1158:20138] array0 = (
A,
B,
C
) 指针地址 = 0x600002880e40
2020-04-02 21:17:57.475197+0800 CopyDemo[1158:20138] array1 = (
A,
B,
C
) 指针地址 = 0x600002880e10
2020-04-02 21:17:57.475409+0800 CopyDemo[1158:20138] array2 = (
A,
B,
C
) 指针地址 = 0x600002880e10
2020-04-02 21:17:57.475544+0800 CopyDemo[1158:20138] array3 = (
A,
B,
C
) 指针地址 = 0x600002880ae0
2020-04-02 21:17:57.475714+0800 CopyDemo[1158:20138] array0 = (
OK,
YES,
NO
) 指针地址 = 0x60000289cfc0
2020-04-02 21:17:57.475853+0800 CopyDemo[1158:20138] array1 = (
A,
B,
C,
D
) 指针地址 = 0x600002880e10
2020-04-02 21:17:57.475990+0800 CopyDemo[1158:20138] array2 = (
A,
B,
C,
D
) 指针地址 = 0x600002880e10
2020-04-02 21:17:57.476128+0800 CopyDemo[1158:20138] array3 = (
A,
B,
C
) 指针地址 = 0x600002880ae0
分析:
(1) array0 = @[@“A”, @“B”, @“C”]; array0指向@[@“A”, @“B”, @“C”]的内存空间,地址为0x600002880e40
(2) copy操作如果来源对象是可变对象(NSMutableArray),则拷贝对象内容,也就是深拷贝
array1 = [array0 mutableCopy]; array1重新开辟一块内存空间,拷贝array0的内容,新的地址是0x600002880e10
(3) array2 = array1; array2和array1指向同一块内存空间,内容相同,地址是0x600002880e10
(4) array3 = [array1 mutableCopy],array3重新开辟一块内存空间,拷贝array1的内容,新的地址是0x600002880ae0
在array0 = @[@“OK”, @“YES”, @“NO”];
[array1 addObject:@“D”];
这两行语句之前:
(1) array0 = @[@“A”, @“B”, @“C”]; array0指向@[@“OK”, @“YES”, @“NO”]的内存空间,地址变成新的地址0x60000289cfc0
(2) [array1 addObject:@“D”];array1增加一个新的元素@“D”,内容变成@[@“A”, @“B”, @“C”, @“D”]。地址不变,仍是0x600002880e10
(3) array2和array1指向同一块内存空间,内容、地址和array1一样
(3) array3的地址和array1不一样,不受影响。内容还是@[@“A”, @“B”, @“C”]