copy--mutableCopy用法(important)

简介: 1 // 2 // main.m 3 // cope-MultableCopy 4 // 5 // Created by dingxiaowei on 13-5-19.
复制代码
  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
复制代码
相关文章
|
安全 API 数据安全/隐私保护
深入浅出python代码混淆:原理与实践
代码混淆就像是给你的代码穿上了一件隐形衣。它可以让你的代码变得难以理解,但并不能完全保证代码的安全。在实际应用中,我们应该将代码混淆作为整个安全策略中的一环,而不是唯一的防线。
|
8月前
|
数据安全/隐私保护 SoC
基于PI控制的三相整流器控制系统的simulink建模与仿真,包含超级电容充电和电机
本课题基于MATLAB 2022a的Simulink平台,构建了PI控制的三相整流器控制系统,用于PMSM电机发电并为超级电容充电。系统通过调节电流和电压,实现高效能量管理和动力输出。核心模块包括三相整流器、超级电容及其显示模块、PI控制器。仿真结果无水印,完整展示了系统性能。系统原理涵盖交流转直流、超级电容快速充放电及电机驱动,适用于多种工况下的能量管理。
|
应用服务中间件 Linux 调度
干货!几个 Nginx 性能优化方法
干货!几个 Nginx 性能优化方法
242 0
|
IDE Java 持续交付
探索开发者工具箱:提升生产力的利器
在软件开发中,选择合适的工具能够显著提升效率和产品质量。本文介绍了开发者常用的工具,包括代码编辑器(如 Visual Studio Code、Sublime Text)、版本控制系统(如 Git、SVN)、集成开发环境(如 IntelliJ IDEA、Eclipse)、调试工具(如 GDB、Chrome DevTools)、构建工具(如 Maven、Webpack)、CI/CD 工具(如 Jenkins、Travis CI)、API 和文档生成工具(如 Swagger、Doxygen),以及项目管理工具(如 Jira、Trello)。
|
机器学习/深度学习 安全 网络协议
智能家居安全:技术与挑战
本文将深入探讨智能家居系统的安全性问题,从技术角度分析当前面临的主要威胁和解决策略。通过具体案例说明如何加强智能家居的数据保护和隐私安全,同时指出未来研究的方向。
394 2
|
运维 监控 Linux
"熬夜达人揭秘:Linux系统崩溃前夜,如何用这几行代码救局?监控与排查全攻略!"
【8月更文挑战第19天】作为常需熬夜的系统管理员,面对Linux系统问题时,我总结了一套实用的监控与排查方法。通过使用`top`监控CPU使用率、`free`检查内存状况、`iostat`监测磁盘I/O、及`iftop`观察网络流量,结合`ps`、`pmap`和`strace`等工具深入分析,可有效识别并解决系统瓶颈,减少故障处理时间,保障系统稳定运行。
132 0
|
前端开发 数据安全/隐私保护
利用 HBuilderX 设置CSS样式会员注册页面
利用 HBuilderX 设置CSS样式会员注册页面
296 1
|
存储 弹性计算 运维
中小企业使用阿里云无影云电脑可以做哪些事情?
阿里云无影云电脑为中小企业提供低成本、弹性、安全的桌面服务。用户可随时随地访问,灵活调整配置,便捷分享文件,确保数据安全,并简化运维管理。现推出优惠,如4核8G内存版本低至98.99元/年,8核16G仅398元/年。
375 0
|
资源调度 前端开发 JavaScript
如何用 Bower 管理前端资源:提升开发效率与项目维护性
【7月更文挑战第2天】**Bower**是基于Node.js的前端包管理器,用于高效管理JavaScript库、CSS和HTML模板等资源。通过安装、配置、搜索、安装、更新及卸载组件,它帮助开发者保持依赖的一致性,提升开发效率。配置`.bowerrc`设定安装目录,`bower.json`记录依赖。遵循最佳实践,如定期更新、锁定版本和清理无用组件,能增强项目维护性。尽管有新工具出现,掌握Bower仍是前端开发基础。
332 0
Qt实用技巧:对QPushButton(等类似透明有黑色背景的QWidget实现透明/半透明的方法
Qt实用技巧:对QPushButton(等类似透明有黑色背景的QWidget实现透明/半透明的方法
Qt实用技巧:对QPushButton(等类似透明有黑色背景的QWidget实现透明/半透明的方法