oc中的拷贝分为:copy(浅拷贝)和mutablecopy(深拷贝)。
浅拷贝也为指针拷贝,拷贝后原来的对象计数器会+1;
深拷贝为对象拷贝,原来的对象计数器不变。
注意:自定义对象拷贝时要实现NSCoping协议或NSMutableCopying协议.且构造方法和copyWithZone方法中最好用[self class]来代替类名
下面以NSString的拷贝 和Student,DoodStudent的copy(实现NSCoping协议)为例展示:
OC学习基本快告一段落了,终于可以见到IOS界面了呵呵呵呵。。。。。闲话少说直接上代码:
主函数:
// // main.m // Copy // // Created by WildCat on 13-7-27. // Copyright (c) 2013年 wildcat. All rights reserved. // #import <Foundation/Foundation.h> #import "Student.h" #import "GoodStudent.h" #pragma mark 练习mutablecopy语法(深拷贝)对象拷贝。 void mutablecopyTest(){ NSString *string =[[NSString alloc] initWithFormat:@"Age is %i",10]; //调用MutableCopy方法,产生一个可变的对象,MutableCopy后的对象和原来的对象不是同一个对象 ,原来的对象和新建的对象的计数器都是1 NSMutableString *str=[string mutableCopy]; [str appendString:@" no is 123"]; NSLog(@"String's:%@ :count is %zi,\n str's: %@: count is %zi",string,[string retainCount],str,[str retainCount]); [str release]; [string release]; } #pragma mark copy的练习 copy是浅拷贝(指针拷贝),对象只是做了retain操作 void copyTest(){ NSString *string =[[NSString alloc] initWithFormat:@"Age is %i",10]; //调用Copy方法,产生一个可变的对象,copy后的对象和原来的对象是同一个对象 ,对象的计数器都是+1 NSLog(@"Count:%zi",[string retainCount]); NSString *str=[string copy]; NSLog(@"Count:%zi",[string retainCount]); NSLog(@"%i",str==string); [str release]; [string release]; } void studentNameCopy(){ Student *stu=[[[Student alloc] init] autorelease]; NSMutableString *str=[NSMutableString stringWithFormat:@"Jack"]; stu.name=str; NSLog(@"name is :%@",stu.name); [str appendString:@" 你好。"]; NSLog(@"name is :%@",stu.name); //因为是用的copy方法 ,所以内容不变。如果用retain name会变 NSLog(@"str is:%@",str); } void copyStudent(){ Student *stu1=[Student studentWithName:@"lixingle"]; Student *stu2=[stu1 copy]; NSLog(@"Name1 is :%@",stu1.name); NSLog(@"Name2 is :%@",stu2.name); stu1.name=@"lele"; NSLog(@"Name1 is :::%@",stu1.name); NSLog(@"Name2 is :::%@",stu2.name); [stu2 release]; } #pragma mark GOOdStudent 的copy练习 void goodStudentCopy(){ GoodStudent *good1=[GoodStudent goodStudentWithAge:10 Name:@"乐乐"]; GoodStudent *good2=[good1 copy]; //改变good1,good2不会变 good1.name=@"长超"; NSLog(@"good1: %@",good1); NSLog(@"good2: %@",good2); [good2 release]; } int main(int argc, const char * argv[]) { @autoreleasepool { //copyTest(); //studentNameCopy(); //copyStudent(); goodStudentCopy(); } return 0; }
Student类(例子中父类)
#import <Foundation/Foundation.h> //对象Copy需要实现NSCoping协议 @interface Student : NSObject<NSCopying> //NSString 对象一般用copy,外边的内容改变里边的内容不变。retain:当外边的内容改变时里边的内容也会改变 //其他对象建议用retain @property (nonatomic,copy) NSString *name; +(id)studentWithName:(NSString *) name; -(id)copyStudent; @end
// // Student.m // Copy // // Created by WildCat on 13-7-27. // Copyright (c) 2013年 wildcat. All rights reserved. // #import "Student.h" @implementation Student @synthesize name=_name; +(id)studentWithName:(NSString *) name{ //这里用[self class] ,方便子类调用 Student *stu=[[[[self class] alloc] init] autorelease]; stu.name=name; return stu; } #pragma mark 实现协议 //实现协议,要实现copyWithZone 方法 -(id)copyWithZone:(NSZone *)zone{ //这里创建的对象不需要释放,在外边释放 ;这里用[self class] ,方便子类调用 Student *stu=[[[self class] allocWithZone:zone] init]; stu.name=self.name; return stu; } - (void)dealloc { [_name release]; [super dealloc]; } //重写description方法 -(NSString *)description{ return [NSString stringWithFormat:@"name is %@",self.name]; } @end
GoodStudent类(子类)
#import "Student.h" @interface GoodStudent : Student @property (nonatomic,assign)int age; +(id) goodStudentWithAge:(int) age Name:(NSString *)name; @end
#import "GoodStudent.h" @implementation GoodStudent +(id) goodStudentWithAge:(int) age Name:(NSString *)name{ GoodStudent *good=[GoodStudent studentWithName:name]; good.age=age; return good; } -(id)copyWithZone:(NSZone *)zone{ GoodStudent *copy=[super copyWithZone:zone]; copy.age=self.age; return copy; } -(NSString *)description{ return [NSString stringWithFormat:@"name is :%@,age is:%i,",self.name,self.age]; } @end