转载:http://www.cocoachina.com/ios/20180428/23197.html
主要通过 NSString、NSMutableString 通过简单的小例子来深入介绍,可变对象和不可变对象使用 copy mutableCopy 得到的结果来说明,理解了 深浅拷贝之 对@property 引用计数关键字的理解和原理就能更加清晰明了。
一、NSString
//分析字符串 深浅拷贝
- (void)analyzeString
{
NSString* string = @"StringJerseyCafe";
// 浅拷贝、未生成新地址、对指针进行了一份拷贝、指向原对象地址所指向的同一份内容。
NSString* copyString = [string copy];
// 深拷贝、生成了新的内存地址、对内容也进行了一份拷贝、使用新的内存地址指向新的内容。
NSMutableString* mutableCopyString = [string mutableCopy];
// 图一:
NSLog(@"String = %@-%p --- copyString = %@-%p ---- mutableCopyString = %@-%p/n", string, string, copyString, copyString, mutableCopyString, mutableCopyString);
// 证明浅拷贝和深拷贝原理。
string = @"Jersey";
// 直接改变 string、 其实相当于将 string 重新分配一份内存地址。
// 从copyString 可以看出、 因为其对 String 的指针地址进行了一份拷贝。 然后使用其同样的内存地址,指向的内容还是同一份。 所以当 string 改变了之后、 并没有影响到自己。
// mutableCopyString 更加不可能影响,其拷贝了一份内容,然后生成另一份内存地址。 指向拷贝出来的这份内容。
// 图二:
NSLog(@"String = %@-%p --- copyString = %@-%p ---- mutableCopyString = %@-%p/n", string, string, copyString, copyString, mutableCopyString, mutableCopyString);
}
图一
图2
结论:不可变对象 copy 生成不可变对象,拷贝方式为浅拷贝。 执行 mutableCopy 生成可变对象,拷贝方式为深拷贝。
二、NSMutableString
//分析可变字符串 深浅拷贝
- (void)analyzeMutableString
{
NSMutableString* mutableString = [NSMutableString stringWithString:@"MutableStringJerseyCafe"];
// 可变字符串copy、 拷贝其内容,生成一份新地址 指向这份内容。 得到不可变字符串。
NSMutableString* copyMutableString = [mutableString copy];
NSMutableString* mutableCopyMutableString = [mutableString mutableCopy];
// 可变字符串 不管是执行 copy、 mutableCopy 都是深拷贝。 因为其都是生成一份新地址,然后对原有内容进行一份拷贝。使新地址指向拷贝出来的同一份内容。 所以下面的改变原有字符串内容, 也不会两个 深拷贝出来的对象。唯一区别是 copy 得到不可变字符串,mutableCopy 得到可变字符串。 看见下面拼接验证。
// 图三:
NSLog(@"mutableString = %@-%p --- copyMutableString = %@-%p ---- mutableCopyMutableString = %@-%p/n", mutableString, mutableString, copyMutableString, copyMutableString, mutableCopyMutableString, mutableCopyMutableString);
[mutableString appendFormat:@"改变可变字符串内容"];
NSLog(@"mutableString = %@-%p --- copyMutableString = %@-%p ---- mutableCopyMutableString = %@-%p/n", mutableString, mutableString, copyMutableString, copyMutableString, mutableCopyMutableString, mutableCopyMutableString);
// 验证 mutableString copy 生成对象。 使用其拼接字符串、 直接导致崩溃、 其属于字符串而非可变字符串。
// [copyMutableString appendFormat:@"TestcopyMutableString"];
// 验证 mutableString mutableCopy 生成对象。 使用其拼接字符串、 返回结果正常、 其属于可变字符串而非字符串。
[mutableCopyMutableString appendFormat:@"TestmutableCopyMutableString"];
NSLog(@"mutableCopyMutableString = %@-%p/n", mutableCopyMutableString, mutableCopyMutableString);
}
图三
图四
图五
结论: 可变对象 copy 生成不可变对象,拷贝方式为深拷贝。 执行 mutableCopy 生成可变对象,拷贝方式为深拷贝。
网友评论