OC提供了强大copy语法,让我们copy一个对象作为副本,改变副本对象而不影响原来的对象,而copy分为深拷贝也就是内容拷贝,用于可变类型的拷贝,拷贝之后会产生新的对象,计数器为1,还有就是浅拷贝也就是地址拷贝,用于不可变的对象拷贝,因为对象本身不可变,在copy的时候,源对象会被直接返回并不会创建新的对象,拷贝后计数器加1。只有不可变对象copy为不可变对象的时候才是浅拷贝。
//深拷贝 void strMutableCopy(){ NSString *str=[[NSString alloc]initWithFormat:@"abcd"]; //产生了一个新的对象 计数器为1 源对象的计数器不变 NSMutableString *str2=[str mutableCopy]; [str2 appendString:@"123456"]; NSLog(@"str.count=%zi",[str retainCount]); NSLog(@"str.count=%zi",[str2 retainCount]);
//不是相同对象 NSLog(@"%i",str2==str);
NSLog(@"str=%@",str); NSLog(@"str2=%@",str2);
[str release]; [str2 release]; } //浅拷贝 指针拷贝 不会产生新的对象,源对象计数器加1 void strCopy(){ NSString *str=[[NSString alloc]initWithFormat:@"abcd"]; //因为NSString对象本身就不可变,所以并没产生新的对象,而是返回对象本身,会做一次retain操作,所以源对象也会retain NSString *str2=[str copy]; NSLog(@"%zi",[str retainCount]); NSLog(@"%i",str2==str); [str release]; [str2 release]; } |
//可变字符串的拷贝 深拷贝 void mutableCopy(){ NSMutableString *str=[[NSMutableString alloc]initWithFormat:@"abcd"];
//会产生一个新的对象计数器1 NSString *str2=[str copy]; [str2 release]; } //深拷贝 void mutableStringCopy(){ NSMutableString *str=[NSMutableString stringWithFormat:@"555"]; //会产生一个新的对象 计数器为1 NSMutableString *str2=[str mutableCopy]; [str2 release]; } |
深拷贝和浅拷贝在内存中如下:
在对象copy的时候,该类必须实现协议NSCopying,并且必须重写copyWithZone方法
Student类
#import <Foundation/Foundation.h> @interface Student : NSObject <NSCopying> @property (nonatomic,assign)int age; //代表会release旧对象 copy新对象 //修改外面的变量,并不会影响到内部的成员变量 //NSString 一般用copy策略,其他用retain @property (nonatomic,copy)NSString *name; +(id)studentWithName:(NSString *) name; -(void)study; @end |
#import "Student.h" @implementation Student -(void)study{ NSLog(@"正在学习的学生是%i",_age); } +(id)studentWithName:(NSString *)name{ Student *stu=[[[[self class] alloc]init]autorelease]; stu.name=name; return stu; } -(void)setName:(NSString *)name{ if(name!=_name){ [_name release]; _name=[name copy]; } } -(void)dealloc{ [_name release]; [super dealloc]; } #pragma mark copying协议
-(id)copyWithZone:(NSZone *)zone{ //不要求释放,因为使用copy的地方会释放 Student *stu=[[[self class] allocWithZone:zone ]init]; //copy姓名 stu.name=self.name; return stu; } -(NSString *)description{ return [NSString stringWithFormat:@"当前对象的名字是%@",_name]; } @end |
#import "Student.h" @interface GoodsStudent : Student @property (assign,nonatomic)int no; +(id)goodsStudentWithNo:(int)no name:(NSString *)name; @end |
#import "GoodsStudent.h"
@implementation GoodsStudent +(id)goodsStudentWithNo:(int)no name:(NSString *)name{ GoodsStudent *goods=[GoodsStudent studentWithName:name]; goods.no=no; return goods; } -(id)copyWithZone:(NSZone *)zone{ GoodsStudent *stu= [super copyWithZone:zone]; stu.no=self.no; return stu; } -(NSString *)description{ return [NSString stringWithFormat:@"name=%@,no=%i",self.name,_no]; } @end |
void objectcopy(){ Student *stu=[[[Student alloc]init]autorelease];
NSMutableString *str=[NSMutableString stringWithFormat:@"zhangsan"];
stu.name=str;
[str appendString:@"111"]; NSLog(@"name=%@",[stu name]); } void objectCopy2(){ Student *stu1=[Student studentWithName:@"zhangsan"]; Student *stu2=[stu1 copy]; NSLog(@"stu=%@",stu2); } void objCopy4(){ GoodsStudent *stu=[GoodsStudent goodsStudentWithNo:89757 name:@"cooljune"]; GoodsStudent *stu2=[stu copy]; stu2.name=@"asdasd"; NSLog(@"stu2---%@",stu2); NSLog(@"stu---%@",stu); } |