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