copy语法
copy 和 mutableCopy
一个对象使用copy或者mutableCopy方法可以创建对象的副本
---------------
copy - 需要先实现NSCopying协议,创建的是不可变副本(如NSString,NSArray,NSDictionary)
---------------
mutableCopy - 需要先实现NSMutableCopying协议,创建的是可变副本(如NSMutableString,NSMutableArray,NSMutableDictionary,默认都已经实现)
像自己创建 的 Person Student 是不可以拷贝的,因为没有实现这两个协议中的一个。
---------------
深拷贝:内容拷贝,源对象和副本指向的是不同的两个对象,源对象引用计数器不变,副本计数器设置为1。内容拷贝。区别:有没有产生新对象。
---------------
浅拷贝:指针拷贝,源对象和副本指向的是同一个对象。对象的引用计数器+1,其实相当于做了一次retain操作。地址拷贝。
---------------
只有不可变对象创建的不可变副本(copy)才是浅复制,其他的都是深复制。
OC中copy语法存在的意义就是改变副本不影响源对象。
所以只跟调用的方法名有关系,跟源对象没关系。
内存管理回顾
#pragma mark mutablecopy
void stringMutablecopy(){
//string counter 1
NSString *string=[[NSString alloc] initWithFromat:@”age is %1”,10];
//str counter 1,string counter 1
// Create a new Object it’s counter is 1,source object counter is 1
NSMutableString *str=[string mutableCopy];
NSLog(@”str=%zi”,[str retainCount]); //1
NSLog(@”string=%zi”,[string retainCount]);//1
//so copy release
//not the same Object
NSLog(@”%i”,str==string);//0
//Modify str to check whether string change
[str appendString:@”abcd”];
NSLog(@”string:%@”,string);
NSLog(@”str:%@”,str);
[str release];//str:0
//string counter 0
[string release];
}
#pragma mark copy
void(){
NSString *string=[[NSString alloc] initWithFromat:@”age is %1”,10];
NSLog(@”%zi”,[string retainCount]);
NSString *str=[string copy];// Both can’t change
//浅拷贝 相当于retain ,因为str不可变,为了性能着想,所以返回源对象本身,计数器+1
NSLog(@”%i”,str==string);//1
NSLog(@”%zi”,[string retainCount]);
[str release];
[string release];
}
//结论不论是copy 还是 mutableCopy 都需要release
#praga mark mutable->copy 可变字符串的拷贝
void mutableStringCopy(){
NSMutableString * string=[NSMutableString stringWithFormat:@”age is %i”,10];
NString *str=[string copy];// 深拷贝
NSLog(@“%i”,str==string);
[str release];
}
void mutableStringMutableCopy(){
//肯定是深拷贝
NSMutableString * string=[NSMutableString stringWithFormat:@”age is %i”,10];
NSMutableString * str=[string mutableCopy];
[str appendString:@”1234”];
NSLog(@”str:%@”,str);
NSLog(@”string:%@”,string);
[str release];
}
自己创建的类来拷贝
Student.h
//@property (nonatomic ,retain) NSString *name;
Student.m
//retain代表set方法会release旧对象,retain新对象
-(void)setName:(NSString *)name{
if(_name!=name){
[_name release];
_name=[name retain];
}
}
-(void)dealloc{
[_name release];
[super dealloc];
}
Student.h
//修改外部的变量并不会影响到内部成员
@property (nonatomic ,copy) NSString *name;
Student.m
//copy代表set方法会release旧对象,copy新对象
-(void)setName:(NSString *)name{
if(_name!=name){
[_name release];
_name=[name copy];
}
}
-(void)dealloc{
[_name release];
[super dealloc];
}
//pragma mark show copy name of Student (前面的懂,这就模糊了)
#import “Student.h”
void studentNameCopy(){
Student *stu=[[[Student alloc] init]autorelease];
NSMutableString *string=[NSMutableString stringWithFormat:@”age is %i”,10];
stu.name=string;
[string appendString;@“123”];
NSLog(@”name=%@”,stu.name);//10
NSLog(@”string=%@”,string);//10123
}
//字符串建议一般用copy,其他对象一般用retain
#pragma mark copy Student copy
Student.h
@interface Student:NSObject<NSCopying>
@property (nonatomic,copy) NSString *name;
+(id)studentWithName:(NSString *)name;
@end
Student.m
@implementation Student
+(id)studentWithName:(NSString *)name{
//Student *stu=[[[Studeent alloc]init]autorelease];
Student *stu=[[[[self class]alloc]init]autorelease];
//self 指向方法调用者
stu.name=name;
return stu;
}
-(void)dealloc{
[_name release];
[super dealloc];
}
//description 你能打印 self 会死循环的
-(NSString *)description{
return [NSString stringWithFormat:@“[name=%@]”,_name];
//后面GoodStudent需要
}
#pagma mark method in copying protocol zone 指向新的存储空间
-(id)copyWithZone:(NSZone *)zone{
Student *copy=[[[self class]allocWithZone:zone]init];//此处不要求释放
copy.name=self.name;//拷贝名字给副本对象
return copy;//谁调用谁释放,交给外界释放
}
@end
void student Copy(){
Student stu1=[Student studentWithName:@”stu1”];
Student stu2=[stu1 copy];
//print stu1 & stu2
NSLog(@”stu1:%@”,stu1);//stu1
NSLog(@”stu2:%@”,stu2);//stu1
stu2.name=@”stu2”;
NSLog(@”stu1:%@”,stu1);//stu1
NSLog(@”stu2:%@”,stu2);//stu2
[stu2 release];
}
#pragma mark GoodStudent inherit Student
GoodStudent.h
@interface GoodStudent : Student
@property (nonatomic,assign) int age;
+(id)goodStudentWithAge:(int)age name:(NSString *)name;
@end
GoodStudent.m
@implemrntation GoodStudent
+(id)goodStudentWithAge:(int)age name:(NSString *)name{
GoodStudent *good=[GoodStudent studentWithName:name];
//这样写返回的good是student对象
//所以student 方法应该是 Student *stu=[[[[self class]alloc]init]autorelease];
good.age=age;
return good;
}
-(id)copyWithZone:(NSZone *)zone{
//一定要调用父类的方法
GoodStudent *copy=[super copyWithZone:zone];
copy.age=self.age;
return copy;
}
-(NSString *)description {
return [NSString stringWithFomat:@”[name=%@,age=%i]”,self.name,_age];
//注意访问不了_name ,_name是Student内部私有
}
@end
main.m
#import “GoodStudent.h”
void goodStudentCopy(){
GoodStudent *stu1=[GoodStudent goodStudentWithAge:10 name;@”good1”];
GoodStudeent *stu2=[stu1 copy];
NSLog(@”stu1:%@”,stu1);
NSLog(@”stu2:%@”,stu2);
stu2.name=@”good2”;
stu2.age=@”11”;
NSLog(@”stu1:%@”,stu1);
NSLog(@”stu2:%@”,stu2);
}
key point:
copy语法的更多相关文章
- OC之Copy语法
转载请注明:http://www.cnblogs.com/letougaozao/p/3631105.html 概念 内存管理 NSString的copy实例 对象的copy实例 一.概念 目的:在改 ...
- [OC Foundation框架 - 17] copy语法
一个对象使用copy或mutableCopy方法可以创建对象的副本 1.copy 需要实现NSCopying协议 创建出来的是不可变副本,如NSString, NSArray, NSDictionar ...
- OC中@property属性关键字的使用(assign/weak/strong/copy)
OC中@property属性关键字的使用(assign/weak/strong/copy) 一.assign 用于 ‘基本数据类型’.‘枚举’.‘结构体’ 等非OC对象类型 eg:int.bool等 ...
- spring BeanUtils 工具实现对象之间的copy
一般我们会开发中会遇到返回用户信息的时候,不需要返回密码或者其他参数,这时候我们需要重新定义一个VO类去除不需要的参数,将原对象copy到VO类中 使用spring的BeanUtils可以实现对象的c ...
- oc总结 --oc基础语法相关知识
m是OC源文件扩展名,入口点也是main函数,第一个OC程序: #import <Foundation/Foundation.h> int main(int argc, const cha ...
- OC总结 【OC基础语法相关知识】
m是OC源文件扩展名,入口点也是main函数,第一个OC程序: #import <Foundation/Foundation.h> int main(int argc, const cha ...
- OC Copy and MutableCopy的使用
#import <Foundation/Foundation.h> @interface Student : NSObject <NSCopying> // copy代表set ...
- Docker指令集
FROM 语法:FROM <image>[:<tag>] 解释:设置要制作的镜像基于哪个镜像,FROM指令必须是整个Dockerfile ...
- ios深拷贝,浅拷贝,拷贝自定义对象的简单介绍(转)
copy语法的目的:改变副本的时候,不会影响到源对象: 深拷贝:内容拷贝,会产生新的对象.新对象计数器置为1,源对象计数器不变. 浅拷贝:指针拷贝,不会产生新的对象.源对象计数器+1. 拷贝有下面两个 ...
随机推荐
- 用bisect来管理已排序的序列
bisect 模块包含两个主要函数,bisect 和 insort,两个函数都利用二分查找算法来在有序序列中查找或插入元素. 2.8.1 用bisect来搜索 bisect(haystack, nee ...
- 怎样设置cookie的到期时间
1. 使用Cookie的: Expires 属性. 它可以设置cookie的过期时间. 下面的代码表示id这条cookie的过期时间是2015年10月21日早上7点28分; Set-Cookie: i ...
- 怎样设置Cookie
因为 Cookie 是服务器保存在浏览器中的一小段信息, 因此这个设置应当是服务器发起的, 设置方法是在Response Header中添加: Set-Cookie字段, 值是多个键值对. 如下: / ...
- Skywalking的增强与拦截机制
整理自架构经理(汤哥)的分享 字节增强条件匹配 在 skywalking 中实现很多基于 byte-buddy 的关于链式匹配查询的实现, 代码如下所示: public abstract class ...
- SpringBoot-JPA入门
SpringBoot-JPA入门 JPA就是Spring集成了hibernate感觉. 注解,方法仓库(顾名思义的方法,封装好了,还有自定义的方法). 案例: spring: datasource: ...
- JavaScript 的查询机制——LHS 与 RHS
JavaScript 引擎在查找一个变量的时候,有两种查找机制:LHS 和 RHS. RHS 的查询是简单地查找到某个变量的值,而 LHS 则是试图找到变量的容器的本身. 一个简单的例子:当我们执行 ...
- 系统性能分析-vmstat命令详解
最近温馨巩固Linux 操作系统的 vmstat命令,这个命令所能打印的系统信息满多的,比较好用,就顺当记录下重要的点,方便以后排查系统问题时拿出来用 字段 含义 procs 进程信息字段: -r:正 ...
- ZPL语言完成条形码的打印
近期因为项目的需求,需要使用到打印机来打印业务相关的条形码和其他信息,由于之前有操作其它打印机的经验,Leader就安排我来做这个了(凑哦,这能说我是懵逼的么).于是就开始了我的探索之旅啦,不对,是踩 ...
- 从0到1写rtos:事件的挂起
任务的状态: 未创建:只定义了任务代码,未调用tTaskInit()初始化 就绪:任务已经创建完毕,且等待机会占用CPU运行 运行:任务正在占用CPU运行代码 延时:任务调用tTaskDelay()延 ...
- Sublime text3安装
一.Sublime text3下载 [20190506]下载 官网下载:https://www.sublimetext.com/ https://download.sublimetext.com/Su ...