本篇寄语:
青天为屋瓦,日月做窗棂,四三五岳为梁柱,天地犹如一敞厅
copy 与mutableCopy
很多人都有这样的误会:copy== 浅拷贝? mutableCopy == 深拷贝
NO! NO! NO!
是深拷贝还是浅拷贝不能仅仅根据copy和mutableCopy来判断,还要看被拷贝的对象
对象
对象 |
类 |
遵守协议 |
不可变对象 |
NSString NSArray NSSet NSDictionary NSAttributedString
|
NSCopying NSMutableCopying
|
可变对象 |
NSMutableString NSMutableString NSMutableSet NSMutableDictionary NSMutableAttributedString
|
NSCopying NSMutableCopying
|
标量对象 |
NSNumber NSValue
|
NSCopying |
操作
操作 |
不可变对象(NS*) |
可变的对象(NSMutable*) |
标量对象 |
copy |
浅拷贝 |
深拷贝 |
同assign |
mutableCopy |
深拷贝 |
深拷贝 |
cash |
拷贝
名称 |
描述 |
占用内存 |
旧对象引用计数 |
拷贝后的对象 |
对象中包含的对象 |
浅拷贝 |
拷贝指针 |
不会改变 |
+1 |
为不可变对象 |
地址不变 |
深拷贝 |
拷贝对象 |
*2 |
+0 |
为可变对象 |
地址不变 |
赋值(=) |
拷贝指针 |
不会改变 |
+1 |
和原对象保持一致 |
地址不变 |
代码
NSLog(@"NSArray");
RCTest * test = [[RCTest alloc] init];
NSArray * arr = [NSArray arrayWithObject:test];
NSLog(@"init :%p,%@",arr,arr);
id arrE = arr;
NSLog(@"equal :%@:%p,%@",[arrE class],arrE,arrE);
id arrCopy = [arr copy];
NSLog(@"copy :%@:%p,%@",[arrCopy class],arrCopy,arrCopy);
id arrMutableCopy = [arr mutableCopy];
NSLog(@"mutableCopy:%@:%p,%@",[arrMutableCopy class],arrMutableCopy,arrMutableCopy);
NSLog(@"NSMutableArray");
RCTest * test1 = [[RCTest alloc] init];
NSMutableArray * marr = [NSMutableArray arrayWithObject:test1];
NSLog(@"init :%p,%@",marr,marr);
id marrE = marr;
NSLog(@"equal :%@:%p,%@",[marrE class],marrE,marrE);
id marrCopy = [marr copy];
NSLog(@"copy :%@:%p,%@",[marrCopy class],marrCopy,marrCopy);
id marrMutableCopy = [marr mutableCopy];
NSLog(@"mutableCopy:%@:%p,%@",[marrMutableCopy class],marrMutableCopy,marrMutableCopy);
NSLog(@"NSNumber");
NSNumber * number = [NSNumber numberWithBool:YES];
NSLog(@"init :%p,%@,%@",number,number,[number valueForKey:@"retainCount"]);
id numberCopy = [number copy];
NSLog(@"copy :%p,%@,%@ - %@",numberCopy,numberCopy,[number valueForKey:@"retainCount"],[numberCopy valueForKey:@"retainCount"]);
id numberMutableCopy = [number mutableCopy];
NSLog(@"copy :%p,%@,%@ - %@",numberMutableCopy,numberMutableCopy,[number valueForKey:@"retainCount"],[numberMutableCopy valueForKey:@"retainCount"]);
日志
2018-12-01 18:07:56.838444+0800 TestApp[3527:165370] NSArray
2018-12-01 18:07:56.839175+0800 TestApp[3527:165370] init :0x600000017440,(
"<RCTest: 0x6000000171f0>"
)
2018-12-01 18:07:56.839629+0800 TestApp[3527:165370] equal :__NSSingleObjectArrayI:0x600000017440,(
"<RCTest: 0x6000000171f0>"
)
2018-12-01 18:07:56.840314+0800 TestApp[3527:165370] copy :__NSSingleObjectArrayI:0x600000017440,(
"<RCTest: 0x6000000171f0>"
)
2018-12-01 18:07:56.840764+0800 TestApp[3527:165370] mutableCopy:__NSArrayM:0x6040000504a0,(
"<RCTest: 0x6000000171f0>"
)
2018-12-01 18:07:56.841474+0800 TestApp[3527:165370] NSMutableArray
2018-12-01 18:07:56.841731+0800 TestApp[3527:165370] init :0x60000025c350,(
"<RCTest: 0x600000017540>"
)
2018-12-01 18:07:56.841941+0800 TestApp[3527:165370] equal :__NSArrayM:0x60000025c350,(
"<RCTest: 0x600000017540>"
)
2018-12-01 18:07:56.842167+0800 TestApp[3527:165370] copy :__NSSingleObjectArrayI:0x600000017580,(
"<RCTest: 0x600000017540>"
)
2018-12-01 18:07:56.842431+0800 TestApp[3527:165370] mutableCopy:__NSArrayM:0x60000025c4d0,(
"<RCTest: 0x600000017540>"
)
2018-12-01 18:07:56.842616+0800 TestApp[3527:165370] NSNumber
2018-12-01 18:07:56.842882+0800 TestApp[3527:165370] init :0x109062390,1,1152921504606846975
2018-12-01 18:07:56.843076+0800 TestApp[3527:165370] copy :0x109062390,1,1152921504606846975 - 1152921504606846975
2018-12-01 18:07:56.843364+0800 TestApp[3527:165370] -[__NSCFBoolean mutableCopyWithZone:]: unrecognized selector sent to instance 0x109062390
2018-12-01 18:07:57.124815+0800 TestApp[3527:165370] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFBoolean mutableCopyWithZone:]: unrecognized selector sent to instance 0x109062390'
*** First throw call stack:
网友评论