copy--mutableCopy用法(important)

简介:
  1 //   2 //  main.m   3 //  cope-MultableCopy   4 //   5 //  Created by dingxiaowei on 13-5-19.   6 //  Copyright (c) 2013年 dingxiaowei. All rights reserved.   7 //   8    9 #import <Foundation/Foundation.h>  10 #import "Student.h"  11 #import "GoodStudent.h"  12 //copy语法的目的:改变副本的时候,不会影响到原对像  13   14 //只有一种情况是浅拷贝,不可变对象调用copy方法,才是浅拷贝  15   16 #pragma mark - 演示字符串的mutableCopy语法(深拷贝)  17 //深拷贝:是内容拷贝,会产生新对象,新对象计数器加1,原对象不变  18 void stringmutableCopy(){  19   20     NSString *str=[[NSString alloc] initWithFormat:@"hello,%i。",10];  21     NSLog(@"%@",str);  22     //复制一个对象  23     //产生一个新对象,计数器为1,原对象计数器不变  24     NSMutableString *mustr=[str mutableCopy];  25     NSLog(@"str:%zi",[str retainCount]);  26     NSLog(@"mustr:%zi",[mustr retainCount]);  27   28     //判断是否是不同对象,str与mustr不是相同对象  29     NSLog(@"%i",str==mustr);  30   31     //拼接一个字符串  32     [mustr appendString:@"I am dingxiaowei"];  33     NSLog(@"原来str%@",str);  34     NSLog(@"现在mustr%@",mustr);  35   36     [mustr release];  37     [str release];  38 }  39 #pragma mark - 演示字符串的Copy语法(浅拷贝)  40 //浅拷贝:是地址拷贝,不会产生新对象,原对象计数器加1  41 void stringCopy(){  42     NSString *str=[[NSString alloc] initWithFormat:@"hi%i",10];  43     NSLog(@"str:%zi",[str retainCount]);  44     //copy产生的是不可变副本,由于原对像本来就不可变,所以为了性能着想,copy直接返回原对像本身  45     NSString *newstr=[str copy];  46     NSLog(@"str:%zi",[str retainCount]);  //由于是同一个对象,所以相当于str进行了一次retain操作  47     NSLog(@"newstr:%zi",[newstr retainCount]);  48     //返回值为1,说明还是返回的原来的对象,相当于return操作  49     NSLog(@"是否相同:%i",str==newstr);  50   51     //执行两次release之后,才能完全释放该对象  52     [str release];  53     [newstr release];  54     //NSLog(@"%zi",[str retainCount]);  55 }  56 #pragma mark - 可变字符串的copy(深拷贝)  57 void mutableStringCopy(){  58     NSMutableString *string=[NSMutableString stringWithFormat:@"age is %i",10];  59     //会产生一个新对象,计数器加1  60     NSString *str=[string copy];  61     //判断是否是同一个对象  62     NSLog(@"%i",string==str);  63   64   65     [str release];  66 //    NSLog(@"%zi",[str retainCount]);  67 }  68 #pragma mark - 可变字符串的mutableCopy方法(深拷贝)  69 void mutableStringmutableCopy(){  70     NSMutableString *string=[NSMutableString stringWithFormat:@"age is %i",10];  71   72     //产生一个新的对象,计数器加1  73     NSMutableString *str=[string mutableCopy];  74     [str appendString:@"  附加的字符串"];  75     NSLog(@"%@",str);  76     NSLog(@"%@",string);  77     [str release];  78 }  79 #pragma mark - 演示Student的name的copy方法  80 void studentNameCopy(){  81     Student *stu=[[[Student alloc] init] autorelease];  82     NSMutableString *string=[NSMutableString stringWithFormat:@"age is %i",10];  83     stu.name=string;  84     [string appendString:@"  append string"];  85     //如果前面写的是Property(retain)NSString*name,那么这两句打印的结果就是一样的  都附加了string  86     NSLog(@"name=%@",stu.name);  87     //拷贝名字给副本对象  88     Student *stucopy=[stu copy];  89   90     //打印两个对象  91     NSLog(@"Stu1:%@",stu);  92     NSLog(@"Stu2:%@",stucopy);  93   94     //因为内部实现的时候没有release,所以这里要必须释放对象  95     [stucopy release];  96   97 }  98 #pragma mark - 演示StudentCopy方法  99 void studentCopy(){ 100     Student *stu=[Student studentWithName:@"stu1"]; 101     Student *stu2=[stu copy]; 102  103     NSLog(@"stu1:%@",stu); 104     NSLog(@"修改前stu2:%@",stu2); 105     stu2.name=@"stu2"; 106     NSLog(@"修改后stu2:%@",stu2); 107  108     [stu2 release]; 109 } 110 #pragma mark - goodstudent的copy演示 111 void goodstudentCopy(){ 112     GoodStudent *goodstudent=[GoodStudent goodstudentWithAge:20 Name:@"dingxiaowei"];  //这里要注意:调用的父类初始化方法,要在父类初始化方法里写一个【self class】alloc来创建一个初始化对象,返回一个子类的对象 113     NSLog(@"%@",goodstudent); 114     GoodStudent *newgoodstudent=[goodstudent copy];  //注意:这儿调用copy方法的时候,会取调用ocopywithzone方法,由于GoodStudent中没有实现,所以会取调用父类的这个方法,返回又会是父类对象,所以这里要注意修改父类方法里面那个方法的初始化对象,改成【self class】,或者对这个方法子类进行重写 115     NSLog(@"stu1:%@",goodstudent); 116     NSLog(@"修改前的stu2:%@",newgoodstudent);  //发现成功拷贝了 117  118     //修改stu2信息 119     newgoodstudent.name=@"cl"; 120     newgoodstudent.age=22; 121     NSLog(@"修改后的stu2:%@",newgoodstudent); 122 } 123 int main(int argc, const char * argv[]) 124 { 125  126     @autoreleasepool { 127          128 //        stringmutableCopy(); 129 //        stringCopy(); 130 //        mutableStringCopy(); 131 //        mutableStringmutableCopy(); 132 //        studentNameCopy(); 133 //        studentCopy(); 134         goodstudentCopy(); 135     } 136     return 0; 137 }

Student.h

 1 #import <Foundation/Foundation.h>  2   3 @interface Student : NSObject<NSCopying>  //要实现NSCopying协议,才能调用类的copy方法  4 //copy代表set方法会先release旧对象,然后copy新对象  5 //用copy的话,修改外部的变量就不会印象到内部的成员变量  6 //建议:一般NSString用copy,其他对象用retain策略  7 //@property(nonatomic,copy)NSString *name;  8 @property(nonatomic,retain)NSString *name;  9  10 -(id)copyWithZone:(NSZone *)zone; 11  12 +(id)studentWithName:(NSString *)name; 13 @end

Student.m

 1 #import "Student.h"  2   3 @implementation Student  4   5 //-(void)setName:(NSString *)name{  6 //    if(_name!=name){  7 //        [_name release];  8 //        //_name=[name retain]; //如果前面是Property(nonautomic,retain)所做的事情  9 //        //如果前面是Property(nonautomic,copy) 10 //        _name=[name copy]; 11 //    } 12 //} 13  14 +(id)studentWithName:(NSString *)name{ 15     Student *stu=[[[[self class] alloc] init] autorelease]; //注意,这里[self class]取代Student 就是为了防止如果子类调用父类的方法,则返回的是父类的对象,会产生错误,所以这么操作就是返回子类的对象 16     stu.name=name; 17     return stu; 18 } 19 -(NSString *)description{ 20     return [NSString stringWithFormat:@"[name=%@]",_name]; 21 } 22  23 #pragma mark - copying方法 24 -(id)copyWithZone:(NSZone *)zone{ 25     //注意:这里创建的copy对象,不要释放对象,因为我们在外面调用copy方法然后释放对象,在这里就不需要释放了 26     Student *copy=[[[self class] allocWithZone:zone] init];  //这里要特别注意:防止子类直接调用这个copywithzone方法而返回的是父类对象,要改成【self class】 27     copy.name=self.name; 28     return copy; 29 } 30  31 -(void)dealloc{ 32     [_name release]; 33     [super release]; 34 } 35 @end

GoodStudent.h

 1 #import "Student.h"  2   3 @interface GoodStudent : Student  4 //assign帮我们自动生成set和get方法  5 @property(nonatomic,assign) int age;  6   7 //-(void)setAge:(int)age;  8 //-(int)age;  9  10 +(id)goodstudentWithAge:(int) age  Name:(NSString *)name; 11 @end

GoodStudent.m

 1 #import "GoodStudent.h"  2   3 @implementation GoodStudent  4   5 //-(void)setAge:(int)age{  6 //    _age=age;  7 //}  8 //-(int)age{  9 //    return _age; 10 //} 11  12 +(id)goodstudentWithAge:(int)age Name:(NSString *)name{ 13     GoodStudent *goodstudent=[GoodStudent studentWithName:name];  //这个要注意可能返回的是父类对象,要在父类中修改 14     goodstudent.age=age; 15     return goodstudent; 16 } 17 //特别注意,description方法里面不能打印self本对象,不然会出现死循环 18 -(NSString *)description{ 19     return [NSString stringWithFormat:@"goodStudent age is %i and name is %@",self.age,self.name]; 20 } 21  22 //由于父类的copywithzone方法只实现了name的copy而没有实现子类特有属性的copy,所以要重写那个copywithzone方法 23 -(id)copyWithZone:(NSZone *)zone{ 24     //首先要调用父类的这个方法 25     GoodStudent *copygoodstu=[super copyWithZone:zone]; 26     copygoodstu.age=self.age; 27     return copygoodstu; 28 } 29  30 @end

















本文转自蓬莱仙羽51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366491,如需转载请自行联系原作者

相关文章
|
1月前
|
前端开发
使用display:inline-block会产生什么问题?解决方法?
【10月更文挑战第27天】使用`display: inline-block`时可能会出现空白间隙和垂直对齐等问题,但通过上述相应的解决方法,可以有效地克服这些问题,实现更精确、更美观的页面布局效果。
|
6月前
|
存储 Python
copy
【6月更文挑战第10天】
41 0
|
前端开发
display:contents
display:contents
59 1
|
7月前
|
算法 C++ 容器
【C++11算法】find_if_not、 copy_if、copy_n
【C++11算法】find_if_not、 copy_if、copy_n
141 0
background引起错误:Error inflating class
background引起错误:Error inflating class
187 0