1.前言
開發(fā)過程中常常需要拷貝屬性、容器且预、模型烙无,修改拷貝對象,是否會對原對象產生影響等涮拗,這就是 copy
與mutableCopy
的區(qū)別
2.copy與mutableCopy的官方解釋
- copy = 淺拷貝
- 拷貝了對象的指針迂苛,兩者指向同一內存地址
- 拷貝對象與原對象的關系就是
影子與本尊
的關系
- mutableCopy = 深拷貝
- 拷貝了對象的內容三幻,兩者指不同內存地址
- 拷貝對象與原對象的關系就是
克隆人與本尊
的關系
圖片有誤內存地址應該不同
3.NSString
與NSMutableString
的深淺拷貝
- 被拷貝對象為NSString
mutableCopy
產生了一個新的對象, copy
修飾的對象則指向了同一內存地址
- 被拷貝對象為NSMutableString
無論是 mutableCopy
還是copy
產生的對象都是新對象念搬。
適用于NSArray
NSMutableArray
NSDictionary
NSMutableDictionary
4.自定義對象實現(xiàn)深淺拷貝
- 聲明自定義類,如果不實現(xiàn)
NSCopying
,NSMutableCopying
協(xié)議夷野,則不具備深淺拷貝的能力 - 使用runtime實現(xiàn)拷貝
- (id)copyWithZone:(NSZone *)zone {
Warrior *warer = [Warrior new];
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList(self.class, &count);
for (int i = 0; i<count; i++) {
objc_property_t propertyNameString = properties[i];
const char *name = property_getName(propertyNameString);
NSString *propertyName = [NSString stringWithUTF8String:name];
id value = [self valueForKey:propertyName];
if (value) {
[warer setValue:value forKey:propertyName];
}
}
free(properties);
return warer;
}
// or
- (id)copyWithZone:(NSZone *)zone {
Striker *ster = [Striker new];
ster.name = @"athey";
ster.gunshot = 550.f;
return ster;
}
5.Property修飾符copy與strong的區(qū)別
- copy修飾符
@property (nonatomic, strong) NSMutableArray *skills;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"fire",@"water",@"ice", nil];
warer.skills = arr;
- 這里的賦值操作就是執(zhí)行setter方法
- (void)setSkills:(NSMutableArray *)skills{
// copy修飾符 生成新的對象
_skills = [skills copy];
}
- 生成新的對象且不可變
// 如果執(zhí)行 NSMutableArray的方法,則會crash
[warer.skills addObject:@"soil"];
Demo地址
個人Blog:allenchou.xyz