1、对象copy概念
使用copy 会产生一个副本
修改副本,不会改变原对象
OC中的copy,就是指的是对象的拷贝
使用copy功能
需要遵守NSCopying协议,实现copyWithZone:方法
copy : 创建一个不可变副本(如NSString、NSArray、NSDictionary)
copy的对象是不可变 那么copy出来的就是不可变副本
mutableCopy: 创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictioanry)
创建一个mac项目
@autoreleasepool{
Dog *d = [Dog new];
//Dog *d2 = [d copy];//这是错误的写法
//例如
//NSString 遵守了NSCopying协议和NSMutableCopying协议
}
创建一个IOS项目
NSString *str = @"abc";
NSLog(@"str = %@ str's addr = %p",str,str);
NSString *str2 = [str copy];
NSLog(@"str2 = %@ str's addr = %p",str str);
NSMutableString *mstr = [NSMutableString string];
[mstr appendString:@"abc"];
NSMutableString *mstr2 = [mstr copy];
[mstr2 appendString:@"xxxxx"];
NSLog(@"mstr2 = %@", mstr2);//输出abcxxxxx
注意:mutableCopy就是深复制,会再内存中重新分配一块内存空间
2. 深拷贝和浅拷贝 内存管理
//在IOS项目中
//创建一个字符串,copy一个不可变副本
NSString *str = [NSString stringWithFormat:@"abc"]; //1
NSString *str2 = [str copy];//2
NSLog(@"str.retainCount = %lu str addr = %p",str.retainCount, str);
NSLog(@"str2.retainCount = %lu str2 addr = %p",str2.retainCount, str2);
//打印出来后,str和str2的内存地址是一样的,str2的引用计数是2,str的引用计数是1,这就是浅拷贝
//mutableCopy一个可变的副本
NSMutableString *str3 = [str mutableCopy];
NSLog(@"str3.retainCount = %lu str3 addr = %p",str3.retainCount,str3);
NSLog(@"str.retainCount = %lu str addr = %p",str.retainCount,str);
//打印出来后,str和str3是在两块内存存储,各自的引用计数为1,这就是深拷贝
copy与内存管理
1.深复制 (深拷贝,内容拷贝,deep copy)
1) 源对象和副本对象是不同的两个对象
2) 源对象引用计数器不变,副本对象计数器为1(因为它是新产生的)
2.浅复制(浅拷贝,指针拷贝,shaddow copy)
1) 源对象和副本对象是同一个对象
2) 源对象(副本对象)引用计数器 +1 相当于做了一次retain操作
本质没有产生新的对象
3. @Property中的copy关键字
在MRC机制下,成员变量如果是OC对象类型,
那么必须重写dealloc方法,在dealloc方法里,
将该这个OC对象发送一次release
@property (nonatomic,retain) NSString *name;
Person *p = [Person new];
//1
p.name = @"john";
NSLog(@"p.name = %@",p.name);
//2
NSMutableString *mstr = [NSMutableString string];
[mstr appendString:@"john silver"];
p.name = mstr;
NSLog(@"p.name = %@", mstr);//打印john silver
[mstr appendString:@"&ken"];
NSLog(@"p.name = %@", p.name);//打印john silver&ken
这肯定是不行的,我要改成&ken 它变成john silver&ken
所有我们把成员变量改成
@property (nonatomic,copy) NSString *name;
并且在dealloc方法里发送release消息
[_name release];
@property内存管理策略和选择
1.MRC机制下
1) copy : 只用于NSString\Block
2) retain: 除了NSString\Block以外的OC对象
3) assign: 基本数据类型,枚举,结构体(非OC对象),当2个对象相互引用,一端用
2.ARC机制下
1) copy : 只用于NSString\block
2) strong:除NSString\block以外的OC对象
3) weak : 当2个对象相互引用,一端用strong,一端用weak
4) assign:基本数据类型,枚举,结构体(非OC对象)
4.为自定义的类实现copy操作
步骤:
1.让Person类遵守NSCopying协议
2.实现copyWithZone:方法 ,在该方法中返回一个对象的副本即可
3.在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,并返回该对象
4.创建Person对象,调用copy方法,查看地址
@interface Person : NSObject<NSCopying,NSMutableCopying>
@property (nonatomic,assign) int age;
@property (nonatomic,assign) int height;
@end
@implementation Person
//当我们每次调用copy,系统就会帮我们处理copyWithZone方法
//该方法就是创建一个新的对象,对象里的值和当前调用该方法的对象保持一致,并将它返回
//自定义对象的copy都是深拷贝
-(id)copyWithZone:(NSZone*)zone{
Person *p = [[Person alloc] init];
p.age = self.age;
p.height = self.height;
return p;
}
@end
int main(){
Person *p = [Person new];
p.age = 22;
p.height = 180;
NSLog(@"p.age = %d, p.height = %d", p.age, p.height);
Person *p1 = [p copy];
NSLog(@"p1.age = %d, p1.height = %d", p1.age, p1.height);
//这样就达到了自定义copy,这种是深拷贝,两个对象完全不一样
return 0;
}
使用copy 会产生一个副本
修改副本,不会改变原对象
OC中的copy,就是指的是对象的拷贝
使用copy功能
需要遵守NSCopying协议,实现copyWithZone:方法
copy : 创建一个不可变副本(如NSString、NSArray、NSDictionary)
copy的对象是不可变 那么copy出来的就是不可变副本
mutableCopy: 创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictioanry)
创建一个mac项目
@autoreleasepool{
Dog *d = [Dog new];
//Dog *d2 = [d copy];//这是错误的写法
//例如
//NSString 遵守了NSCopying协议和NSMutableCopying协议
}
创建一个IOS项目
NSString *str = @"abc";
NSLog(@"str = %@ str's addr = %p",str,str);
NSString *str2 = [str copy];
NSLog(@"str2 = %@ str's addr = %p",str str);
NSMutableString *mstr = [NSMutableString string];
[mstr appendString:@"abc"];
NSMutableString *mstr2 = [mstr copy];
[mstr2 appendString:@"xxxxx"];
NSLog(@"mstr2 = %@", mstr2);//输出abcxxxxx
注意:mutableCopy就是深复制,会再内存中重新分配一块内存空间
2. 深拷贝和浅拷贝 内存管理
//在IOS项目中
//创建一个字符串,copy一个不可变副本
NSString *str = [NSString stringWithFormat:@"abc"]; //1
NSString *str2 = [str copy];//2
NSLog(@"str.retainCount = %lu str addr = %p",str.retainCount, str);
NSLog(@"str2.retainCount = %lu str2 addr = %p",str2.retainCount, str2);
//打印出来后,str和str2的内存地址是一样的,str2的引用计数是2,str的引用计数是1,这就是浅拷贝
//mutableCopy一个可变的副本
NSMutableString *str3 = [str mutableCopy];
NSLog(@"str3.retainCount = %lu str3 addr = %p",str3.retainCount,str3);
NSLog(@"str.retainCount = %lu str addr = %p",str.retainCount,str);
//打印出来后,str和str3是在两块内存存储,各自的引用计数为1,这就是深拷贝
copy与内存管理
1.深复制 (深拷贝,内容拷贝,deep copy)
1) 源对象和副本对象是不同的两个对象
2) 源对象引用计数器不变,副本对象计数器为1(因为它是新产生的)
2.浅复制(浅拷贝,指针拷贝,shaddow copy)
1) 源对象和副本对象是同一个对象
2) 源对象(副本对象)引用计数器 +1 相当于做了一次retain操作
本质没有产生新的对象
3. @Property中的copy关键字
在MRC机制下,成员变量如果是OC对象类型,
那么必须重写dealloc方法,在dealloc方法里,
将该这个OC对象发送一次release
@property (nonatomic,retain) NSString *name;
Person *p = [Person new];
//1
p.name = @"john";
NSLog(@"p.name = %@",p.name);
//2
NSMutableString *mstr = [NSMutableString string];
[mstr appendString:@"john silver"];
p.name = mstr;
NSLog(@"p.name = %@", mstr);//打印john silver
[mstr appendString:@"&ken"];
NSLog(@"p.name = %@", p.name);//打印john silver&ken
这肯定是不行的,我要改成&ken 它变成john silver&ken
所有我们把成员变量改成
@property (nonatomic,copy) NSString *name;
并且在dealloc方法里发送release消息
[_name release];
@property内存管理策略和选择
1.MRC机制下
1) copy : 只用于NSString\Block
2) retain: 除了NSString\Block以外的OC对象
3) assign: 基本数据类型,枚举,结构体(非OC对象),当2个对象相互引用,一端用
2.ARC机制下
1) copy : 只用于NSString\block
2) strong:除NSString\block以外的OC对象
3) weak : 当2个对象相互引用,一端用strong,一端用weak
4) assign:基本数据类型,枚举,结构体(非OC对象)
4.为自定义的类实现copy操作
步骤:
1.让Person类遵守NSCopying协议
2.实现copyWithZone:方法 ,在该方法中返回一个对象的副本即可
3.在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,并返回该对象
4.创建Person对象,调用copy方法,查看地址
@interface Person : NSObject<NSCopying,NSMutableCopying>
@property (nonatomic,assign) int age;
@property (nonatomic,assign) int height;
@end
@implementation Person
//当我们每次调用copy,系统就会帮我们处理copyWithZone方法
//该方法就是创建一个新的对象,对象里的值和当前调用该方法的对象保持一致,并将它返回
//自定义对象的copy都是深拷贝
-(id)copyWithZone:(NSZone*)zone{
Person *p = [[Person alloc] init];
p.age = self.age;
p.height = self.height;
return p;
}
@end
int main(){
Person *p = [Person new];
p.age = 22;
p.height = 180;
NSLog(@"p.age = %d, p.height = %d", p.age, p.height);
Person *p1 = [p copy];
NSLog(@"p1.age = %d, p1.height = %d", p1.age, p1.height);
//这样就达到了自定义copy,这种是深拷贝,两个对象完全不一样
return 0;
}