copy及其用法
来源:互联网 发布:mac 顿号 编辑:程序博客网 时间:2024/06/04 18:05
copy的概念特点
- copy产生一个新副本的过程,利用一个原对象产生一个新对象
- copy:创建一个不可变的副本(NSString;NSArray;NSDictionary;)
- mutableCopy :创建一个可变的副本 (NSMutableDictionary; NSMutableArray;NSMutableString)
- 修改新文件,不会影响原文件
- 修改原文件,不会影响新文件
//会生成新对象 /* 拷贝出来的对象中的内容和以前内容一致 一般情况下拷贝生成一个新的对象 ·因为拷贝要求修改原来的对象不能影响到拷贝出来的对象,修改拷贝出来的对象不能影响到原来的对象,所以需要生成一个新对象 ·由于以前的对象是一个不可变的对象,而通过mutableCopy拷贝出来的对象必须是一个可变的对象,所以需要生成一个新对象 */ NSString * str = @"demo"; NSMutableString *copyStr = [str mutableCopy]; NSLog(@"str = %@ copyStr = %@",str,copyStr); NSLog(@"str = %p copyStr = %p",str,copyStr); NSLog(@""); //会生成新对象 NSMutableString *str1 = [NSMutableString stringWithFormat:@"demo"]; NSMutableString *copyStr1 = [str1 mutableCopy]; [str1 appendString:@"cool"]; NSLog(@"str = %@ copyStr = %@",str1,copyStr1); NSLog(@"str = %p copyStr = %p",str1,copyStr1); NSLog(@""); //会生成新对象 NSMutableString *str2 = [NSMutableString stringWithFormat:@"demo"]; NSString *copyStr2 = [str2 copy]; [str2 appendString:@"cool"]; NSLog(@"str = %@ copyStr = %@",str2,copyStr2); NSLog(@"str = %p copyStr = %p",str2,copyStr2); NSLog(@""); //不会生成新对象 /* 如果是通过不可变对象调用了copy方法,那么不会生成新对象 因为原来的对象时不可修改的,拷贝出来的对象也是不可修改的,既然俩个都不能改,所有永远都不会影响到另一个对象,OC为了堆内存优化,所以就不会生成一个新对象 */ NSString *str3 = @"demo"; NSString *copyStr3 = [str3 copy]; NSLog(@"str = %@ copyStr = %@",str3,copyStr3); NSLog(@"str = %p copyStr = %p",str3,copyStr3);//结果:test2[7366:74428] str = demo copyStr = demotest2[7366:74428] str = 0x100005288 copyStr = 0x100400090test2[7366:74428] test2[7366:74428] str = democool copyStr = demotest2[7366:74428] str = 0x1002000f0 copyStr = 0x10030a2e0test2[7366:74428] test2[7366:74428] str = democool copyStr = demotest2[7366:74428] str = 0x100400780 copyStr = 0x6f6d656445test2[7366:74428] test2[7366:74428] str = demo copyStr = demotest2[7366:74428] str = 0x100005288 copyStr = 0x100005288test2[7366:74428] name = name cooltest2[7366:74428] name = play
- 浅拷贝:如果没有生成新对象我们称为浅拷贝,本质是指针拷贝
- 深拷贝:如果生成了新的对象,我们称为深拷贝,本质就是创建了一个新的对象
- 一般修饰字符串用copy
copy应用
防止外界修改内部数据
@interface Student : NSObject@property (nonatomic,strong) NSString *name;@property (nonatomic,copy) NSString *hobby;@end@implementation Student-(void)dealloc{ NSLog(@"%s",__func__);}@end---------------int main(int argc, const char * argv[]) { NSMutableString *name = [NSMutableString stringWithFormat:@"name"]; NSMutableString *hobby = [NSMutableString stringWithFormat:@"play"]; Student *stu = [[Student alloc]init]; stu.name = name; stu.hobby = hobby; //修改外面对象,影响到了对象的属性 [name appendString:@" cool"]; [hobby appendString:@" football"]; NSLog(@"name = %@",stu.name); NSLog(@"name = %@",stu.hobby);}结果:test2[7405:77750] name = name cooltest2[7405:77750] name = play
copy修饰blcok
block默认存储在栈中,栈中的block访问了外界的对象,不会对对象进行retain
block如果存储在堆中,如果在block中访问了外界的对象,会对外界的对象进行一次retain
typedef void (^myBlock)();typedef void (^myTestBlock)();@interface Student : NSObject@property (nonatomic,strong) myBlock myBlock;//注意;如果是Block使用copy并不是拷贝,而是转移(由栈到堆),从栈到堆,这样可以保持block,避免以后调用block的时候,外界的对象已经释放@property (nonatomic,strong) myTestBlock testBlock;@end@implementation Student-(void)dealloc{ NSLog(@"%s",__func__);}@end-------------------- Student *stu = [[Student alloc]init]; Person *per = [[Person alloc]init]; stu.myBlock = ^{ NSLog(@"%@",per); }; stu.testBlock = ^{ NSLog(@"%@",per); }; stu.myBlock(); stu.testBlock();结果:test2[7941:112357] <Person: 0x100206f80>test2[7941:112357] <Person: 0x100206f80>test2[7941:112357] -[Student dealloc]test2[7941:112357] -[Person dealloc]
关于 copy block之后的循环引用
typedef void (^myTestBlock)();@interface Student : NSObject@property (nonatomic,strong) NSString *name;@property (nonatomic,copy) myTestBlock testBlock;@end@implementation Student-(void)dealloc{ NSLog(@"%s",__func__); [super dealloc];}@end-----------int main(int argc, const char * argv[]) { //如果对象中的block又用到了自己,为了避免内存泄漏,应该将该对象修饰为__block __block Student *stu = [[Student alloc]init]; stu.name = @"ABC"; NSLog(@"1-%lu",stu.retainCount); stu.testBlock = ^{ NSLog(@"%@",stu.name); }; NSLog(@"2-----%lu",stu.retainCount); stu.testBlock(); NSLog(@"3-------%lu",stu.retainCount); [stu release];}结果:test2[8246:125564] 1-1test2[8246:125564] 2-----2test2[8246:125564] ABCtest2[8246:125564] 3-------2test2[8246:125564] -[Student dealloc]
自定义类的实现copy
- 无父类实现
- 让类遵守NSCopying、NSMutableCopying协议
- 实现copyWithZone方法,在该方法中返回一个对象的副本即可
- 在copyWithZone或mutableCopyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,并返回对象
#import <Foundation/Foundation.h>@interface Student : NSObject<NSCopying>@property (nonatomic,copy) NSString *name;@property (nonatomic,assign) int age;@end@implementation Student-(id)copyWithZone:(NSZone *)zone{ //1、创建一个新的对象(zone:表示空间,分配是需要内存空间的,如果指定了zone就可以指定创建对象对应的内存空间,为了避免堆中出现内存碎片而使用的) Student *stu = [[[self class] allocWithZone:zone]init]; //2、设置当前对象的内容给新的对象 stu.name = _name; stu.age = _age; //3、返回新的对象 return stu;}@end---------int main(int argc, const char * argv[]) { Student *stu = [[Student alloc]init]; stu.name = @"abc"; stu.age = 10; Student *stu1 = [stu copy]; Student *stu2 = [stu mutableCopy]; NSLog(@"stu = %@ ,stu1 = %@, stu2 = %@",stu.name,stu1.name,stu2.name); NSLog(@"stu = %d ,stu1 = %d, stu2 = %d",stu.age,stu1.age,stu2.age); NSLog(@"stu = %@ ,stu1 = %@, stu2 = %@",stu,stu1,stu2); return 0;}结果:test2[8511:149031] stu = abc ,stu1 = abc, stu2 = abctest2[8511:149031] stu = 10 ,stu1 = 10, stu2 = 10test2[8511:149031] stu = <Student: 0x100302890> ,stu1 = <Student: 0x1003060b0>, stu2 = <Student: 0x1003061c0>
- 有父类实现
- 不调用父类方法,无法拷贝父类中继承的属性
- 不重写父类copyWithZone方法,无法拷贝本来中特有的属性
@interface Student : NSObject<NSCopying,NSMutableCopying>@property (nonatomic,copy) NSString *name;@property (nonatomic,assign) int age;@end@implementation Student-(id)copyWithZone:(NSZone *)zone{ //1、创建一个新的对象(zone:表示空间,分配是需要内存空间的,如果指定了zone就可以指定创建对象对应的内存空间,为了避免堆中出现内存碎片而使用的) Student *stu = [[[self class] allocWithZone:zone]init]; //2、设置当前对象的内容给新的对象 stu.name = _name; stu.age = _age; //3、返回新的对象 return stu;}-(id)mutableCopyWithZone:(NSZone *)zone{ //1、创建一个新的对象(zone:表示空间,分配是需要内存空间的,如果指定了zone就可以指定创建对象对应的内存空间,为了避免堆中出现内存碎片而使用的) Student *stu = [[[self class] allocWithZone:zone]init]; //2、设置当前对象的内容给新的对象 stu.name = _name; stu.age = _age; //3、返回新的对象 return stu;}@end--------------@interface Boy : Student@property (nonatomic,assign) double height;@end@implementation Boy-(id)copyWithZone:(NSZone *)zone{ //1、创建一个新的对象 id obj = [super copyWithZone:zone]; //2、设置当前对象的内容给新的对象 [obj setHeight:_height]; //3、返回新的对象 return obj;}-(id)mutableCopyWithZone:(NSZone *)zone{ //1、创建一个新的对象 id obj = [super copyWithZone:zone]; //2、设置当前对象的内容给新的对象 [obj setHeight:_height]; //3、返回新的对象 return obj;}-(NSString *)description{ return [NSString stringWithFormat:@"name = %@,age = %d,height =%f",[self name],[self age],_height];}@end-------------int main(int argc, const char * argv[]) { Boy *boy = [[Boy alloc]init]; boy.name = @"abc"; boy.age = 10; boy.height = 1.75; Boy *boy1 = [boy copy]; Boy *boy2 = [boy mutableCopy]; NSLog(@"\nboy = %@ \nboy1 = %@ \nboy2 = %@\n",boy,boy1,boy2); return 0;}
如果想让子类在copy的时候保留子类的属性,那么必须重写copyWithZone方法,在该方法中先调用父类创建副本设置值,然后再设置子类特有的值
阅读全文
0 0
- copy及其用法
- copy 用法。
- Copy命令另类用法
- std::copy 的用法
- Copy命令另类用法
- copy的用法
- STL copy()函数用法
- STL copy 用法
- string copy的用法
- \copy命令的用法
- python_浅copy用法
- Python 的set 类型及其copy方法
- MemberwiseClone 的用法(浅copy)
- Oracle sqlplus copy命令用法
- assign,retain,copy的用法
- ant copy 复制文件用法
- retain copy asign 用法,区别
- copy--mutableCopy用法(important)
- 第三课
- angularJs中orderBy筛选以及filter过滤数据
- JAVA内存存储数据的位置
- 格雷码(多种方法)
- 初见-Java的反射机制
- copy及其用法
- SpringMVC 文件上传与下载(未完待续)
- HBaseAdmin API
- 网络编程
- 浅谈——Java反射机制
- 进程间通讯————消息队列
- 随想录:开发一流Android SDK
- python中的with语句及上下文管理器
- hibernate-关系映射(一对多单向关联)-9