iOS OC中copy和mutableCopy的使用区别

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”]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值