copymutableCopy用法(important)

main:

  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 }
Main Code

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.h Code

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
Student.m Code

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 Code

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
GoodStudent.m Code
原文地址:https://www.cnblogs.com/dingxiaowei/p/3088413.html