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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章