IOS基礎之copy與mutableCopy / 淺拷貝與深拷貝

本篇寄語:
青天爲屋瓦,日月做窗櫺,四三五嶽爲樑柱,天地猶如一敞廳

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:
發佈了53 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章