美文网首页
iOS 关于 copy 的那些事

iOS 关于 copy 的那些事

作者: 笔头还没烂 | 来源:发表于2023-05-28 11:30 被阅读0次
  1. 深拷贝和浅拷贝

    下面先以字符串(NSString、NSMutableString)相关代码为例来作说明,结论看代码中的注释部分即可。而像 NSArray、NSMutableArray、NSDictionary、NSMutableDictionary 实际上道理是相同的。代码如下:

            NSString *str1 = @"hello";
            NSString *str2 = [str1 copy];
            NSMutableString *str3 = [str1 mutableCopy];
            [str3 appendString:@"123"];
            
            NSLog(@"%p,%p,%p",str1,str2,str3);
            //可以正常输出 hello123
            NSLog(@"%@",str3);
            
    //        NSMutableString *str4 = [str1 copy];
            //闪退,因为不可变字符串调用 copy 方法返回的还是不可变字符串,没有 append 方法
    //        [str4 appendString:@"456"];
    //        NSLog(@"%@",str4);
            /*
             小结:
             1. 当不可变字符串调用 copy 方法,返回的是它本身。(浅拷贝,只拷贝指针,不会创建新的对象)
             2. 当不可变字符串调用 mutableCopy 方法,返回的是可变字符串;(深拷贝,创建新的对象)
             */
            NSMutableString *muStr = [[NSMutableString alloc] initWithString:@"test"];
            NSString *str5 = [muStr copy];
            NSMutableString *str6 = [muStr mutableCopy];
            NSLog(@"%p,%p,%p",muStr,str5,str6);
            NSLog(@"%@,%@,%@",muStr,str5,str6);
            
            /*
             小结:
             1. 当可变字符串调用 copy 方法,返回的是不可变字符串(深拷贝,会创建对象)
             2. 当可变字符串调用 mutableCopy 方法,返回的是可变字符串,(深拷贝,会创建对象)
             */
            
            /*
             1. 当不可变字符串调用 copy 方法,返回的是它本身(浅拷贝、不会创建对象);当可变字符串调用 copy 方法,返回的是不可变字符串(深拷贝、会创建对象)
             2. 当不可变字符中调用 mutableCopy 方法,返回的是可变字符串(深拷贝、会创建对象);当可变字符串调用 mutableCopy,返回的是可变字符串(深拷贝、会创建对象)
             3. 只要调用 copy 方法,返回的都是不可变的;
             4. 只要调用 mutableCopy 都是深拷贝
             */
            NSLog(@"=========================================================");
            NSArray *arr = @[@1,@2,@3];
            NSArray *arr2 = [arr copy];
            NSMutableArray *arr3 = [arr mutableCopy];
            NSLog(@"%p,%p,%p",arr,arr2,arr3);
            
            NSMutableArray *muArr = [[NSMutableArray alloc] initWithArray:@[@1,@2,@3]];
            NSArray *arr4 = [muArr copy];
            NSMutableArray *muArr5 = [muArr mutableCopy];
            NSLog(@"%p,%p,%p",muArr,arr4,muArr5);
            
            NSLog(@"=========================================================");
            
            NSDictionary *dict = @{};
            NSDictionary *dict2 = [dict copy];
            NSDictionary *dict3 = [dict mutableCopy];
            NSLog(@"%p,%p,%p",dict,dict2,dict3);
            
            NSLog(@"=========================================================");
            
            NSMutableDictionary *muDict = [[NSMutableDictionary alloc] initWithDictionary:@{}];
            NSDictionary *dict4 = [muDict copy];
            NSMutableDictionary *muDict2 = [muDict mutableCopy];
            NSLog(@"%p,%p,%p",muDict,dict4,muDict2);
    

    输出结果如下:

    0x1022c8060,0x1022c8060,0x6000016e8c60
    hello123
    0x6000016e0000,0xa2adf4aa6953a4ae,0x6000016e0030
    test,test,test

    =========================================================

    0x1022c8200,0x1022c8200,0x6000016e4000
    0x6000016e0060,0x6000016e0150,0x6000016e0270

    =========================================================

    0x1bbd878d8,0x1bbd878d8,0x6000018a46c0

    =========================================================
    0x60000189c120,0x60000189c1a0,0x60000189c1c0

  2. 深拷贝与浅拷贝的 retainCount 值

    结论:对象调用 copy 方法,引用计数不一定会加1,即 引用计数是否加1,要看是否有新对象的产生;

    当不可变字符串调用copy 返回的是它本身,此时没有新对象产生,所以引用计数+1;

    当可变字符串调用copy 方法返回的是一个新的不可变对象,此时因为有新对象产生,所以引用计数从始至终都是1,引用计数不会+1,代码如下:

            NSString *str1 = [[NSString alloc] initWithFormat:@"hello123hello123hello123hello123"];
            NSLog(@"%zd",str1.retainCount);//1
            NSString *str2 = [str1 copy];
            NSLog(@"%zd",str1.retainCount);//2
    
            NSMutableString *muStr = [[NSMutableString alloc] initWithFormat:@"test1234567890test1234567890"];
            NSLog(@"%zd",muStr.retainCount);//1
            NSString *str5 = [muStr copy];
            NSLog(@"%zd",muStr.retainCount);//1
            NSLog(@"%zd",str5.retainCount);//1
    

相关文章

网友评论

      本文标题:iOS 关于 copy 的那些事

      本文链接:https://www.haomeiwen.com/subject/psqdedtx.html