copy語法

copy 和 mutableCopyapp

一個對象使用copy或者mutableCopy方法能夠建立對象的副本性能

---------------atom

copy - 須要先實現NSCopying協議,建立的是不可變副本(如NSString,NSArray,NSDictionary)spa

---------------3d

mutableCopy - 須要先實現NSMutableCopying協議,建立的是可變副本(如NSMutableString,NSMutableArray,NSMutableDictionary,默認都已經實現)指針

像本身建立 的 Person Student 是不能夠拷貝的,由於沒有實現這兩個協議中的一個。orm

---------------對象

深拷貝:內容拷貝,源對象和副本指向的是不一樣的兩個對象,源對象引用計數器不變,副本計數器設置爲1。內容拷貝。區別:有沒有產生新對象。blog

image

---------------ip

淺拷貝:指針拷貝,源對象和副本指向的是同一個對象。對象的引用計數器+1,其實至關於作了一次retain操做。地址拷貝。

image

---------------

只有不可變對象建立的不可變副本(copy)纔是淺複製,其餘的都是深複製。

OC中copy語法存在的意義就是改變副本不影響源對象。

image

因此只跟調用的方法名有關係,跟源對象不要緊。

內存管理回顧

image


#pragma mark mutablecopy

void stringMutablecopy(){

//string counter 1

NSString *string=[[NSString alloc] initWithFromat:@」age is %1」,10];

//str counter 1,string counter 1

// Create a new Object it’s counter is 1,source object counter is 1

NSMutableString  *str=[string mutableCopy];

NSLog(@」str=%zi」,[str retainCount]); //1

NSLog(@」string=%zi」,[string retainCount]);//1

//so copy release

//not the same Object

NSLog(@」%i」,str==string);//0

//Modify str to check whether string change

[str appendString:@」abcd」];

NSLog(@」string:%@」,string);

NSLog(@」str:%@」,str);

[str release];//str:0

//string counter 0

[string release];

}


#pragma mark  copy

void(){

NSString *string=[[NSString alloc] initWithFromat:@」age is %1」,10];

NSLog(@」%zi」,[string retainCount]);

NSString *str=[string copy];// Both can’t change

//淺拷貝 至關於retain ,由於str不可變,爲了性能着想,因此返回源對象自己,計數器+1

NSLog(@」%i」,str==string);//1

NSLog(@」%zi」,[string retainCount]);

[str release];

[string release];

}

//結論不管是copy 仍是 mutableCopy 都須要release


#praga mark mutable->copy 可變字符串的拷貝

void mutableStringCopy(){

NSMutableString * string=[NSMutableString stringWithFormat:@」age is %i」,10];

NString *str=[string copy];// 深拷貝

NSLog(@「%i」,str==string);

[str release];

}

void mutableStringMutableCopy(){

//確定是深拷貝

NSMutableString * string=[NSMutableString stringWithFormat:@」age is %i」,10];

NSMutableString * str=[string mutableCopy];

[str appendString:@」1234」];

NSLog(@」str:%@」,str);

NSLog(@」string:%@」,string);

[str release];

}




本身建立的類來拷貝

Student.h

//@property (nonatomic ,retain) NSString *name;

 

Student.m

//retain表明set方法會release舊對象,retain新對象

-(void)setName:(NSString *)name{

if(_name!=name){

[_name release];

_name=[name retain];

}

}

-(void)dealloc{

[_name release];

[super dealloc];

}

 


Student.h

//修改外部的變量並不會影響到內部成員

@property (nonatomic ,copy) NSString *name;

Student.m

//copy表明set方法會release舊對象,copy新對象

-(void)setName:(NSString *)name{

if(_name!=name){

[_name release];

_name=[name copy];

}

}

-(void)dealloc{

[_name release];

[super dealloc];

}


//pragma mark show copy name of Student (前面的懂,這就模糊了)

#import 「Student.h」

void studentNameCopy(){

Student *stu=[[[Student alloc] init]autorelease];

NSMutableString *string=[NSMutableString stringWithFormat:@」age is %i」,10];

stu.name=string;

[string appendString;@「123」];

NSLog(@」name=%@」,stu.name);//10

NSLog(@」string=%@」,string);//10123

}

//字符串建議通常用copy,其餘對象通常用retain



#pragma mark copy Student copy

image

Student.h

@interface Student:NSObject<NSCopying>

@property (nonatomic,copy) NSString *name;

+(id)studentWithName:(NSString *)name;

@end

Student.m

@implementation Student

+(id)studentWithName:(NSString *)name{

//Student *stu=[[[Studeent alloc]init]autorelease];

Student *stu=[[[[self class]alloc]init]autorelease];

//self 指向方法調用者

stu.name=name;

return stu;

}

-(void)dealloc{

[_name release];

[super dealloc];

}

//description 你能打印 self 會死循環的

-(NSString *)description{

return [NSString stringWithFormat:@「[name=%@]」,_name];

//後面GoodStudent須要

}

#pagma mark method in copying protocol   zone 指向新的存儲空間

-(id)copyWithZone:(NSZone *)zone{

Student *copy=[[[self class]allocWithZone:zone]init];//此處不要求釋放

copy.name=self.name;//拷貝名字給副本對象

return copy;//誰調用誰釋放,交給外界釋放

}

@end

void student Copy(){

Student stu1=[Student studentWithName:@」stu1」];

Student stu2=[stu1 copy];

//print stu1 & stu2

NSLog(@」stu1:%@」,stu1);//stu1

NSLog(@」stu2:%@」,stu2);//stu1

stu2.name=@」stu2」;

NSLog(@」stu1:%@」,stu1);//stu1

NSLog(@」stu2:%@」,stu2);//stu2

[stu2 release];

}


#pragma mark GoodStudent inherit Student

GoodStudent.h

@interface GoodStudent : Student

@property (nonatomic,assign) int age;

+(id)goodStudentWithAge:(int)age name:(NSString *)name;

@end

GoodStudent.m

@implemrntation GoodStudent

+(id)goodStudentWithAge:(int)age name:(NSString *)name{

GoodStudent *good=[GoodStudent studentWithName:name]; 

//這樣寫返回的good是student對象

//因此student  方法應該是 Student *stu=[[[[self class]alloc]init]autorelease];

good.age=age;

return good;

}

-(id)copyWithZone:(NSZone *)zone{

//必定要調用父類的方法

GoodStudent *copy=[super copyWithZone:zone];

copy.age=self.age;

return copy;

}

-(NSString *)description {

return [NSString stringWithFomat:@」[name=%@,age=%i]」,self.name,_age];

//注意訪問不了_name ,_name是Student內部私有

}

@end

main.m

#import 「GoodStudent.h」

void goodStudentCopy(){

GoodStudent *stu1=[GoodStudent goodStudentWithAge:10 name;@」good1」];

GoodStudeent *stu2=[stu1 copy];

NSLog(@」stu1:%@」,stu1);

NSLog(@」stu2:%@」,stu2);

stu2.name=@」good2」;

stu2.age=@」11」;

NSLog(@」stu1:%@」,stu1);

NSLog(@」stu2:%@」,stu2);

}

image

image


key point:

image

相關文章
相關標籤/搜索