-
深拷贝和浅拷贝
下面先以字符串(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 -
深拷贝与浅拷贝的 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 的那些事
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...