本篇寄語:
青天爲屋瓦,日月做窗櫺,四三五嶽爲樑柱,天地猶如一敞廳
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: