iOS - copy、mutableCopy 的学习心得

最近看了网上很多人的博客和讲解,有些地方不是太明白、自己整理下
1、copy的对象 一般可以分为容器对象(例如Array类),和非容器对象(例如NSString类)。
2、一般常用的copy 数组、字典、字符串、类对象这些。下边会一个个的去研究
一、数组
(1)不可变数组

  NSArray *tempArr = [NSArray arrayWithObjects:@"111", nil];

  NSArray *tempArr2 = tempArr.copy;
  NSArray *tempArr3 = tempArr.mutableCopy;

  NSLog(@"指针地址:%p \n 对象实际地址:%p \n",&tempArr,tempArr);
  NSLog(@"指针地址:%p \n 对象实际地址:%p \n",&tempArr2,tempArr2);
  NSLog(@"指针地址:%p \n 对象实际地址:%p \n",&tempArr3,tempArr3);
指针地址:0x7ffeeac4bda8   对象实际地址:0x6000021b6cc0 
指针地址:0x7ffeeac4bda0   对象实际地址:0x6000021b6cc0 
指针地址:0x7ffeeac4bd98   对象实际地址:0x600002f19020 

不可变数组的copy,是浅copy,只是创建了一个新的指针,指向原指针指向的内存地址
不可变数组的mutableCopy,是深copy,创建了新的指针,并且开辟了新的内存,并将原内存的存在的元素copy了过来

(2)可变数组

    NSMutableArray *tempMutArr = [NSMutableArray array];
    [tempMutArr addObject:@"111"];

    NSMutableArray *tempMutArr2 = tempMutArr.copy;
    NSMutableArray *tempMutArr3 = tempMutArr.mutableCopy;

    NSLog(@"可变对象 指针地址:%p \n 对象实际地址:%p \n",&tempMutArr,tempMutArr);
    NSLog(@"可变对象 指针地址:%p \n 对象实际地址:%p \n",&tempMutArr2,tempMutArr2);
    NSLog(@"可变对象 指针地址:%p \n 对象实际地址:%p \n",&tempMutArr3,tempMutArr3);

    if ([tempMutArr2 isKindOfClass:[NSArray class]]) {

    }
 指针地址:0x7ffeee689da8  对象实际地址:0x6000001ceb80 
 指针地址:0x7ffeee689da0  对象实际地址:0x600000d4d5e0 
 指针地址:0x7ffeee689d98  对象实际地址:0x6000001cebb0 

可变数组的copy,是深copy,创建了新的指针,并且开辟了新的内存地址,并copy了原内存地址中存在的元素,但是可变数组经过copy后,变成了不可变数组,如果调用可变数组的方法,会造成crash

可变数组的mutableCopy,是深copy,也是创建了新的指针,开辟新的内存地址,但是,深copy后,还是可变数组,不会造成crash

二、字典
(1)不可变字典

   NSDictionary *tempDict = [NSDictionary dictionary];
   
   NSDictionary *tempDict2 = tempDict.copy;
   NSDictionary *tempDict3 = tempDict.mutableCopy;
 指针地址:0x7ffee5e91da8  对象实际地址:0x7fff806379a0 
 指针地址:0x7ffee5e91da0  对象实际地址:0x7fff806379a0 
 指针地址:0x7ffee5e91d98  对象实际地址:0x600003145ce0 

不可变字典的copy,是浅copy,只是创建了一个新的指针,指向原指针指向的内存地址
不可变字典的mutableCopy,是深copy,创建了新的指针,并且开辟了新的内存,并将原内存的存在的元素copy了过来

(2)可变字典

    NSMutableDictionary *tempDict = [NSMutableDictionary   dictionary];
    
    NSMutableDictionary *tempDict2 = tempDict.copy;
    NSMutableDictionary *tempDict3 = tempDict.mutableCopy;
指针地址:0x7ffee081dda8   对象实际地址:0x600000cdd240 
指针地址:0x7ffee081dda0   对象实际地址:0x600000cdd260 
指针地址:0x7ffee081dd98   对象实际地址:0x600000cdd280 

可变字典的copy,是深copy,创建了新的指针,并且开辟了新的内存地址,并copy了原内存地址中存在的元素,但是可变字典经过copy后,变成了不可变字典,如果调用可变字典的方法,会造成crash

可变字典的mutableCopy,是深copy,也是创建了新的指针,开辟新的内存地址,但是,深copy后,还是可变字典,不会造成crash

三、字符串
(1)不可变字符串

    NSString *tempStr = @"111";
    NSString *tempStr2 = tempStr.copy;
    NSString *tempStr3 = tempStr.mutableCopy;
 指针地址:0x7ffee8c9dda8   对象实际地址:0x106fa4d28 
 指针地址:0x7ffee8c9dda0   对象实际地址:0x106fa4d28 
 指针地址:0x7ffee8c9dd98   对象实际地址:0x60000305f570 

不可变字符串的copy,是浅copy,只是创建了一个新的指针,指向原指针指向的内存地址
不可变字符串的mutableCopy,是深copy,创建了新的指针,并且开辟了新的内存,并将原内存的存在的元素copy了过来

(2)可变字符串

    NSMutableString *tempStr = [[NSMutableString            alloc]initWithString:@"111"];
    NSMutableString *tempStr2 = tempStr.copy;
    NSMutableString *tempStr3 = tempStr.mutableCopy;

 指针地址:0x7ffee51a3da8  对象实际地址:0x600001304210 
 指针地址:0x7ffee51a3da0   对象实际地址:0xdff58c500f0097cb 
 指针地址:0x7ffee51a3d98   对象实际地址:0x600001304240 

可变字符串的mutableCopy,是深copy,也是创建了新的指针,开辟新的内存地址,但是,深copy后,还是可变字符换,不会造成crash

小结:对于可变对象的copy。copy后均为不可变对象,不可再使用可变对象的方法,因为oc是动态语言,所以编写时调用可变对象的方法不会报错,但是会在运行时发生crash

avatar

参考链接
https://www.jianshu.com/p/dcdb56829833

你可能感兴趣的:(iOS - copy、mutableCopy 的学习心得)