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); } |