copy語法

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

}


發佈了53 篇原創文章 · 獲贊 3 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章