标签:object-c copy mutablecopy retain
OC语法中的retain、copy、mutableCopy 大家都基本知道它的基本意思,但是对于mutable类型和immutable类型的处理上有很多童鞋并没有真正测试过,今天就和大家分享下:
1.先来看下immutable类型的非容器类: NSString的retain、copy和mutableCopy的测试
NSString *string = @"abc"; NSString *retainString = [string retain]; NSString *copyString = [string copy]; NSString *mCopyString = [string mutableCopy];
NSLog(@"string:%@ content:%p p:%p", string, string, &string); NSLog(@"retainString:%@ content:%p p:%p", retainString, retainString, &retainString); NSLog(@"copyString:%@ content:%p p:%p", copyString, copyString, ©String); NSLog(@"mCopyString:%@ content:%p p:%p", mCopyString, mCopyString, &mCopyString);
2015-08-07 18:10:44.270 MyTest[834:40452] string:abc content:0x10008c098 p:0x16fd7dcf8 2015-08-07 18:10:44.271 MyTest[834:40452] retainString:abc content:0x10008c098 p:0x16fd7dcf0 2015-08-07 18:10:44.271 MyTest[834:40452] copyString:abc content:0x10008c098 p:0x16fd7dce8 2015-08-07 18:10:44.271 MyTest[834:40452] mCopyString:abc content:0x17807ce00 p:0x16fd7dce0
从日志可以看出:retain、copy、mutableCopy都复制了指针;不同的是retain、copy指针还是指向原值地址,而mutableCopy则是复制了对象。也就是说:retain、copy对immutable 非容器类对象进行了“浅拷贝”,而mutableCopy则是“深拷贝”。
还有一个点需要注意下:对NSString进行了mutableCopy后得到的mCopyString是mutable还是immutable类型的呢?试一下:
[(NSMutableString *)mCopyString appendFormat:@"def"];得到的结果是:
2015-08-08 19:05:15.873 MyTest[865:27257] mCopyString:abcdef content:0x7ffab349c460 p:0x7fff5b4e76c0也就是说:对immutable的NSString进行了mutableCopy后,变成了mutable类型的。
2。再按照相同的方式来查看下mutable类型的非容器类:NSMutableString
NSMutableString *string = [NSMutableString stringWithFormat:@"abc"]; NSMutableString *retainString = [string retain]; NSMutableString *copyString = [string copy]; NSMutableString *mCopyString = [string mutableCopy];打印下每个变量的指针地址和值的地址:
NSLog(@"string:%@ content:%p p:%p", string, string, &string); NSLog(@"retainString:%@ content:%p p:%p", retainString, retainString, &retainString); NSLog(@"copyString:%@ content:%p p:%p", copyString, copyString, ©String); NSLog(@"mCopyString:%@ content:%p p:%p", mCopyString, mCopyString, &mCopyString);结果:
2015-08-08 19:16:47.630 MyTest[954:32260] string:abc content:0x7ff1c97a07a0 p:0x7fff534486a8 2015-08-08 19:16:47.630 MyTest[954:32260] retainString:abc content:0x7ff1c97a07a0 p:0x7fff534486a0 2015-08-08 19:16:47.631 MyTest[954:32260] copyString:abc content:0x7ff1c97a07e0 p:0x7fff53448698 2015-08-08 19:16:47.631 MyTest[954:32260] mCopyString:abc content:0x7ff1c97a0820 p:0x7fff53448690从日志能看出:对NSMutableString进行的操作,copy和mutableCopy进行了“深拷贝”,而retain是“浅拷贝”。
我们改变下string来测试下:
[string appendFormat:@"de"]; NSLog(@"string:%@ content:%p p:%p", string, string, &string); NSLog(@"retainString:%@ content:%p p:%p", retainString, retainString, &retainString); NSLog(@"copyString:%@ content:%p p:%p", copyString, copyString, ©String); NSLog(@"mCopyString:%@ content:%p p:%p", mCopyString, mCopyString, &mCopyString);结果:
2015-08-08 19:23:14.497 MyTest[1020:35070] string:abcde content:0x7fbdf9e936b0 p:0x7fff5c1656a8 2015-08-08 19:23:14.497 MyTest[1020:35070] retainString:abcde content:0x7fbdf9e936b0 p:0x7fff5c1656a0 2015-08-08 19:23:14.497 MyTest[1020:35070] copyString:abc content:0x7fbdf9e928b0 p:0x7fff5c165698 2015-08-08 19:23:14.497 MyTest[1020:35070] mCopyString:abc content:0x7fbdf9e913b0 p:0x7fff5c165690证明:copy和mutableCopy确实是“深拷贝”,所以他们的值还是“abc”。
那retain、copy、和mutableCopy后是mutable类型还是immutable类型的呢?让我们测试下:
[retainString appendFormat:@"de"]; //正确,因为retain后值的地址没有改变 [copyString appendFormat:@"de"]; //错误导致crash,因为copy是深拷贝,新值是immutable的 [mCopyString appendFormat:@"de"]; //正确,因为mutableCopy是深拷贝,新值是mutable的第二个如果运行会导致崩溃,也就是说:NSMutableString进行copy后是immutable类型的,进行mutableCopy后是mutable类型的。
所以如下的申明方式是错误的,mutableString是immutable类型的。
@property(nonatomic, copy) NSMutableString *mutableString;
NSArray *array = @[@"a", @"b", @"c"]; NSArray *retainArray = [array retain]; NSArray *copyArray = [array copy]; NSArray *mCopyArray = [array mutableCopy];
NSLog(@"array:%@ content:%p p:%p", array, array, &array); NSLog(@"retainArray:%@ content:%p p:%p", retainArray, retainArray, &retainArray); NSLog(@"copyArray:%@ content:%p p:%p", copyArray, copyArray, ©Array); NSLog(@"mCopyArray:%@ content:%p p:%p", mCopyArray, mCopyArray, &mCopyArray);结果:
2015-08-08 19:39:16.840 MyTest[1199:42450] array:( a, b, c ) content:0x7f92e0e4e870 p:0x7fff4fc06660 2015-08-08 19:39:16.841 MyTest[1199:42450] retainArray:( a, b, c ) content:0x7f92e0e4e870 p:0x7fff4fc06658 2015-08-08 19:39:16.842 MyTest[1199:42450] copyArray:( a, b, c ) content:0x7f92e0e4e870 p:0x7fff4fc06650 2015-08-08 19:39:16.842 MyTest[1199:42450] mCopyArray:( a, b, c ) content:0x7f92e0c89f30 p:0x7fff4fc06648
从结果来看可以证明:对于immutable类型的容器类NSArray,retain、copy是“浅拷贝”,mutableCopy是“深拷贝”。同样的:mCopyArray是一个mutable类型的
[(NSMutableArray *)mCopyArray addObject:@"d"]; //正确
NSMutableString *mString = [NSMutableString stringWithFormat:@"a"]; NSMutableArray *array = [NSMutableArray arrayWithObjects:mString, @"b", @"c", nil]; NSMutableArray *retainArray= [array retain]; NSMutableArray *copyArray = [array copy]; NSMutableArray *mCopyArray = [array mutableCopy];
NSLog(@"array:%@ content:%p p:%p", array, array, &array); NSLog(@"retainArray:%@ content:%p p:%p", retainArray, retainArray, &retainArray); NSLog(@"copyArray:%@ content:%p p:%p", copyArray, copyArray, ©Array); NSLog(@"mCopyArray:%@ content:%p p:%p", mCopyArray, mCopyArray, &mCopyArray);打印结果:
2015-08-08 19:53:30.541 MyTest[1319:49288] array:( a, b, c ) content:0x7f8f71f45190 p:0x7fff5467f6a0 2015-08-08 19:53:30.541 MyTest[1319:49288] retainArray:( a, b, c ) content:0x7f8f71f45190 p:0x7fff5467f698 2015-08-08 19:53:30.542 MyTest[1319:49288] copyArray:( a, b, c ) content:0x7f8f71f45210 p:0x7fff5467f690 2015-08-08 19:53:30.542 MyTest[1319:49288] mCopyArray:( a, b, c ) content:0x7f8f71f45240 p:0x7fff5467f688
可以看出:同NSMutableString相同,retain是“浅拷贝”,copy、mutableCopy是“深拷贝”。
同样的:
[retainArray addObject:@"d"];//正确 [copyArray addObject:@"d"]; //错误导致crash [mCopyArray addObject:@"d"];//正确
NSMutableString *mString = [NSMutableString stringWithFormat:@"a"]; NSMutableArray *array = [NSMutableArray arrayWithObjects:mString, @"b", @"c", nil]; NSMutableArray *copyArray = [array copy]; NSMutableArray *mCopyArray = [array mutableCopy];mString是array的第一个对象,然后对array进行了”深拷贝“,打印下:
NSLog(@"array:%@ content:%p p:%p", array, array, &array); NSLog(@"copyArray:%@ content:%p p:%p", copyArray, copyArray, ©Array); NSLog(@"mCopyArray:%@ content:%p p:%p", mCopyArray, mCopyArray, &mCopyArray);
2015-08-08 20:01:23.624 MyTest[1413:53021] array:( a, b, c ) content:0x7f8150473240 p:0x7fff523436a0 2015-08-08 20:01:23.625 MyTest[1413:53021] copyArray:( a, b, c ) content:0x7f8150473270 p:0x7fff52343698 2015-08-08 20:01:23.625 MyTest[1413:53021] mCopyArray:( a, b, c ) content:0x7f81504732a0 p:0x7fff52343690
[mString appendFormat:@"aaa"];再打印下:
NSLog(@"array:%@ content:%p p:%p", array, array, &array); NSLog(@"copyArray:%@ content:%p p:%p", copyArray, copyArray, ©Array); NSLog(@"mCopyArray:%@ content:%p p:%p", mCopyArray, mCopyArray, &mCopyArray);让我们看下结果:
2015-08-08 20:01:23.626 MyTest[1413:53021] array:( aaaa, b, c ) content:0x7f8150473240 p:0x7fff523436a0 2015-08-08 20:01:23.626 MyTest[1413:53021] copyArray:( aaaa, b, c ) content:0x7f8150473270 p:0x7fff52343698 2015-08-08 20:01:23.626 MyTest[1413:53021] mCopyArray:( aaaa, b, c ) content:0x7f81504732a0 p:0x7fff52343690
那怎么让“深拷贝”的数组里面的元素也是“深拷贝呢”?也是有方法的:
- (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;
NSMutableString *mString = [NSMutableString stringWithFormat:@"a"]; NSMutableArray *array = [NSMutableArray arrayWithObjects:mString, @"b", @"c", nil]; NSMutableArray *mDeepCopyarray = [[NSMutableArray alloc] initWithArray:array copyItems:YES]; NSLog(@"mDeepCopyarray:%@ content:%p p:%p", mDeepCopyarray, mDeepCopyarray, &mDeepCopyarray); [mString appendFormat:@"aaa"]; NSLog(@"array:%@ content:%p p:%p", array, array, &array); NSLog(@"mDeepCopyarray:%@ content:%p p:%p", mDeepCopyarray, mDeepCopyarray, &mDeepCopyarray);
结果:
2015-08-08 20:09:52.781 MyTest[1492:57289] mDeepCopyarray:( a, b, c ) content:0x7f8988deec60 p:0x7fff5025c698 2015-08-08 20:09:52.782 MyTest[1492:57289] array:( aaaa, b, c ) content:0x7f8988deec30 p:0x7fff5025c6a0 2015-08-08 20:09:52.782 MyTest[1492:57289] mDeepCopyarray:( a, b, c ) content:0x7f8988deec60 p:0x7fff5025c698
版权声明:本文为博主原创文章,未经博主允许不得转载。
OC语法——Object-C retain、copy、mutableCopy的详细分析
标签:object-c copy mutablecopy retain
原文地址:http://blog.csdn.net/wc455287693/article/details/47343021