深浅拷贝的区别:
深拷贝 拷贝 内容
浅拷贝 拷贝 地址
注:当对象str1在常量区时
①对不可变字符串NSString对象进行copy
NSString *str1 = @"Hello"; //str1 -- 常量区
NSLog(@"%p", str1);//0x100002048
//copy
NSString *str2 = [str1 copy];//0x100002048 str2 -- 常量区
NSLog(@"%p", str2);//str2 与 str1都指向常量区,地址相同,引用计数为无穷大
NSLog(@"str2 retaincount = %lu", [str2 retainCount]);<span style="font-size:18px;">//18446744073709551615</span>
②对不可变字符串NSString对象进行mutableCopy
//mutableCopy,深拷贝,拷贝内容,而且拷贝出来的是一个可变的对象
NSMutableString *str3 = [str1 mutableCopy];
NSLog(@"str3 retaincount = %lu", [str3 retainCount]);//1
[str3 appendString:@"world"];//对拷贝出来的对象进行操作
NSLog(@"str3 = %@", str3);
注:当对象str1在堆区
时
NSString *str1 = [NSString stringWithFormat:@"Frank"];
NSLog(@"str1 = %p, retaincount = %lu", str1, [str1 retainCount]);//1
①对不可变字符串NSString对象进行copy
//copy, 浅拷贝, 拷贝 地址, 并且将原有对象的引用计数加1.
NSString *str2 = [str1 copy];// str2与str1指向同一块堆区空间
NSLog(@"str2 = %p, retaincount = %lu", str2, [str2 retainCount]);//2
②对不可变字符串NSString对象进行mutableCopy
//mutableCopy,深拷贝,拷贝内容,堆区开辟新的空间,并且拷贝出来的对象是可变的.
NSMutableString *str3 = [str1 mutableCopy];//str3与str1指向不同的对象
[str3 appendString:@"lanou"];
NSLog(@"str3 = %p, retaincount = %lu", str3, [str3 retainCount]);//1
可变字符串(NSMutable
String)
①对一个可变字符串NSMutableString对象copy
//原有对象str1在堆区
NSMutableString *str1 = [[NSMutableString alloc] initWithFormat:@"Frank"];
NSLog(@"str1 = %p", str1);//0x10010b800
//copy 堆区中开辟新的空间,拷贝内容到新的空间上,但是拷贝出来的是不可变字符串对象.
NSString *str2 = [str1 copy];
NSLog(@"str2 = %p, retaincount = %lu", str2, [str2 retainCount]);//1
②对一个可变字符串NSMutableString对象mutableCopy
//mutableCopy 堆区中开辟新的空间,拷贝内容到新的空间上,但是拷贝出来的是可变字符串对象.
NSMutableString *str3 = [str1 mutableCopy];
[str3 appendString:@"lanou"];
NSLog(@"str3 = %p, retaincount = %lu", str3, [str3 retainCount]);
总结:
/**
* 总结:拷贝是分为可变对象与不可变对象.
浅拷贝 --- 只拷贝对象地址,不会拷贝内容,不会开辟新的空间.
深拷贝 --- 拷贝内容,堆区开辟新的空间.
不可变对象: 1.copy 相当于retin, 原有对象引用计数加1,拷贝地址.
2.mutableCopy 复制出新的对象,并且对象是可变的,开呗内容.
可变对象: 1.copy 复制出新的对象,但是对象是不可变的,拷贝内容.
2.mutableCopy 复制出新的对象,但是对象是可变的,拷贝内容.
*/
③.对一个自定义对象Copy和mutableCopy,需要服从<NSCopying, NSMutableCopying>协议,例如:
1.创建Person.h
@interface Person : NSObject <NSCopying, NSMutableCopying>
@property (nonatomic, copy) NSString *name; //姓名
@property (nonatomic, copy) NSString *gender; //性别
@property (nonatomic) NSInteger age;//年龄
@end
2.Person.m文件服从
协议
@implementation Person
- (id)copyWithZone:(NSZone *)zone
{
Person *newPerson = [[[self class] allocWithZone:zone] init];
newPerson.name = [self.name copy];
newPerson.gender = [self.gender copy];
newPerson.age = self.age;
return newPerson;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
Person *newPerson = [[[self class] allocWithZone:zone] init];
newPerson.name = [self.name mutableCopy];
newPerson.gender = [self.gender mutableCopy];
newPerson.age = self.age;
return newPerson;
}
- (void)dealloc
{
self.name = nil;
self.gender = nil;
[super dealloc];
}
@end
实现,对深浅拷贝分析
//Person copy 与 mutableCopy
NSString *name = [NSString stringWithFormat:@"Wang"];
NSString *gender = [NSString stringWithFormat:@"Man"];
Person *per = [[Person alloc] init];
per.name = name;
per.gender = gender;
NSLog(@"per = %p", per);//0x10010b980
//per name = 0x100100560, gender = 0x100104ac0(拷贝前地址)
NSLog(@"per name = %p, gender = %p", per.name, per.gender);
Person *copyPerson = [per copy];
//copyPerson = 0x100500a90, retaincount = 1(拷贝后地址)
NSLog(@"copyPerson = %p, retaincount = %lu",
copyPerson, [copyPerson retainCount]);
//(拷贝后内容地址不变,把地址拷贝过去)
//copyPerson name = 0x100100560, gender = 0x100104ac0
NSLog(@"copyPerson name = %p, gender = %p",
copyPerson.name, copyPerson.gender);
Person *mutaCopyPerson = [per mutableCopy];
//copymutaCopyPersonPerson = 0x100401d50, retaincount = 1
NSLog(@"copymutaCopyPersonPerson = %p,
retaincount = %lu", mutaCopyPerson, [mutaCopyPerson retainCount]);
//(mutableCopy)地址不同,即拷贝是内容
//mutaCopyPerson name = 0x100401450, gender = 0x1004014e0
NSLog(@"mutaCopyPerson name = %p, gender = %p",
mutaCopyPerson.name, mutaCopyPerson.gender);