深拷贝是对象拷贝,拷贝出一个新的对象.
浅拷贝是指针拷贝,拷贝出一个指针指向原来的对象.在非ARC项目中,原来对象的引用计数加一.
第一,字符串的拷贝
1>不可变字符串调用copy方法,不会产生一个新的对象,是指针的拷贝.
2>不可变字符串调用mutableCopy方法,会产生一个新的对象,是对象的copy
例如:
//1.不可变字符串
NSString *str = @"wang";
//没有产生新对象
NSString *copyStr = [str copy];
//产生新对象
NSString *mutableCopyStr = [str mutableCopy];
NSLog(@"%p,%p,%p",str,copyStr,mutableCopyStr);
运行结果:
2016-04-27 08:41:52.076 深拷贝与浅拷贝[4368:232990] 0x100005260,0x100005260,0x100114b00
3>可变字符串无论使用copy方法还是mutableCopy方法,都会产生一个新对象
//可变字符串
NSMutableString *mutableStr = [NSMutableString stringWithFormat:@"li"];
//可以产生新对象
NSString *copyMutableStr = [mutableStr copy];
//可以产生新对象
NSString *mutableStrCopy = [mutableStr mutableCopy];
NSLog(@"mutableStr = %p,copyMutableStr = %p mutableStrCopy = %p",mutableStr,copyMutableStr,mutableStrCopy);
运行结果:
2016-04-27 08:41:52.078 深拷贝与浅拷贝[4368:232990] mutableStr = 0x100300040,copyMutableStr = 0x696c25 mutableStrCopy = 0x100300180
注意:对于NSArray与NSMutableArray,NSDictionary与NSMutableDictionary情况相同,不可变的对象copy方法不产生一个对象,mutableCopy产生一个新对象.可变的对象,copy与mutableCopy方法均可以产生一个新对象
第二,对象的拷贝,对象的copy类要遵循NSCopying协议,实现-(id)copyWithZone:(NSZone *)zone方法.并且对象的拷贝,拷贝一个新对象,是深拷贝
下面#import "Person.h"为例说明
Person.h文件
@interface Person : NSObject<NSCopying>
/**
* 姓名
*/
@property (nonatomic,copy) NSString *name;
/**
* 身高
*/
@property (nonatomic,assign) int height;
/**
* 年龄
*/
@property (nonatomic,assign) int age;
@end
Person.h文件
-(id)copyWithZone:(NSZone *)zone
{
//实现这个方法,返回任意对象
Person *person = [[Person allocWithZone:zone] init];
return person;
}
运行代码
Person *person = [[Person alloc] init];
person.name = @"wang";
person.age = 20;
person.height = 2;
Person *copyPerson = [person copy];
NSLog(@"copyPerson = %@ person = %@ ,age = %d,name = %@",copyPerson,person,copyPerson.age,copyPerson.name);
运行结果:
2016-04-27 09:01:24.561 深拷贝与浅拷贝[4615:239972] copyPerson = <Person: 0x1004001c0> person = <Person: 0x100400370> ,age = 0,name = (null)
虽然拷贝了新对象,但是age,name并没有值,如果想要在拷贝的同时给新对象赋值.修改.h文件如下面
-(id)copyWithZone:(NSZone *)zone
{
//实现这个方法,返回任意对象
Person *person = [[Person allocWithZone:zone] init];
person.age = self.age;
person.name = self.name;
person.height = self.height;
//这里的self为被拷贝的对象.
return person;
}
第三,copy与strong的区别
1>copy属性
@interface Person : NSObject<NSCopying>
/**
* 姓名
*/
@property (nonatomic,copy) NSString *name;
Person *p = [[Person alloc] init];
NSMutableString *strName = [NSMutableString stringWithFormat:@"你好的"];
p.name = strName;
//不能修改p.name的值,因为内部copy新对象,传入的是strName是可变字符串,copy为深拷贝,不可变字符串是浅拷贝
[strName appendString:@"hahaha"];
NSLog(@"p.age = %p strName = %p p.name = %@",p.name, strName,p.name);
打印结果:
2016-04-27 09:12:56.216 深拷贝与浅拷贝[4741:243819] p.age = 0x10020bd40 strName = 0x10020bd00 p.name = 你好的
注意:p.name实际上是实现了
-(void)setName:(NSString *)name
{
_name = [name copy];
}
2>strong属性
@interface Dog : NSObject<NSCopying>
/**
* 名字
*/
@property (nonatomic,strong) NSString *name;
Dog *dog = [[Dog alloc] init];
NSMutableString *strDogName = [NSMutableString stringWithFormat:@"小红"];
dog.name = strDogName;
[strDogName appendString:@"heihei"];
NSLog(@"dog.name = %@",dog.name);
使用strong属性修饰的时候,是添加了一个强指针的引用,其内部没有生成新的对象