ios深拷贝,浅拷贝,拷贝自定义对象的简单介绍
2016-04-11 11:13
267 查看
copy语法的目的:改变副本的时候,不会影响到源对象;
深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。
浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。
拷贝有下面两个方法实现拷贝:
[objc] view
plain copy
- (id)copy;
- (id)mutableCopy;
要实现copy,必须实现<NSCopying>协议
数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例,其他的同理:
1.不可变字符串调用copy实现拷(浅拷贝)
[objc] view
plain copy
NSString *string = [[NSString alloc] initWithFormat:@"abcde"];
// copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身
// 源对象计数器会+1
// 在浅拷贝情况下,copy其实就相当于retain
NSString *str = [string copy];
2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)
[objc] view
plain copy
NSString *string = [[NSString alloc] initWithFormat:@"abcd"];
// 产生了一个新的对象,计数器为1。源对象的计数器不变。
NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1
// str和string不是相同对象
// NSLog(@"%i", str == string);//0
[str appendString:@" abcd"];//修改str不影响string
NSLog(@"string:%@", string);
NSLog(@"str:%@", str);
3.可变字符串调用copy实现拷贝(深拷贝)
[objc] view
plain copy
NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSString *str = [string copy];
4.可变字符串的MutableCopy(深拷贝)
[objc] view
plain copy
NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSMutableString *str = [string mutableCopy];
[str appendString:@"1234"];//修改新对象不影响原对象
NSLog(@"str:%@", str);
NSLog(@"string:%@", string);
5.拷贝自定义对象,下面以Student对象为例
a.Student要实现copy,必须实现<NSCopying>协议
b.实现<NSCopying>协议的方法:
- (id)copyWithZone:(NSZone *)zone
Student.h文件
[objc] view
plain copy
@interface Student : NSObject <NSCopying>
// copy代表set方法会release旧对象、copy新对象
// 修改外面的变量,并不会影响到内部的成员变量
// 建议:NSString一般用copy策略,其他对象一般用retain
@property (nonatomic, copy) NSString *name;
+ (id)studentWithName:(NSString *)name;
@end
Student.m文件
[objc] view
plain copy
#import "Student.h"
@implementation Student
+ (id)studentWithName:(NSString *)name {
// 这里最好写[self class]
Student *stu = [[[[self class] alloc] init] autorelease];
stu.name = name;
return stu;
}
- (void)dealloc {
[_name release];
[super dealloc];
}
#pragma mark description方法内部不能打印self,不然会造成死循环
- (NSString *)description {
return [NSString stringWithFormat:@"[name=%@]", _name];
}
#pragma mark copying协议的方法
// 这里创建的副本对象不要求释放
- (id)copyWithZone:(NSZone *)zone {
Student *copy = [[[self class] allocWithZone:zone] init];
// 拷贝名字给副本对象
copy.name = self.name;
return copy;
}
@end
拷贝Student
[objc] view
plain copy
Student *stu1 = [Student studentWithName:@"stu1"];
Student *stu2 = [stu1 copy];
stu2.name = @"stu2";
NSLog(@"stu1:%@", stu1);
NSLog(@"stu2:%@", stu2);
[stu2 release];
.小结:
建议:NSString一般用copy策略,其他对象一般用retain;
只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;
深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。
浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。
拷贝有下面两个方法实现拷贝:
[objc] view
plain copy
- (id)copy;
- (id)mutableCopy;
要实现copy,必须实现<NSCopying>协议
数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例,其他的同理:
1.不可变字符串调用copy实现拷(浅拷贝)
[objc] view
plain copy
NSString *string = [[NSString alloc] initWithFormat:@"abcde"];
// copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身
// 源对象计数器会+1
// 在浅拷贝情况下,copy其实就相当于retain
NSString *str = [string copy];
2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)
[objc] view
plain copy
NSString *string = [[NSString alloc] initWithFormat:@"abcd"];
// 产生了一个新的对象,计数器为1。源对象的计数器不变。
NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1
// str和string不是相同对象
// NSLog(@"%i", str == string);//0
[str appendString:@" abcd"];//修改str不影响string
NSLog(@"string:%@", string);
NSLog(@"str:%@", str);
3.可变字符串调用copy实现拷贝(深拷贝)
[objc] view
plain copy
NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSString *str = [string copy];
4.可变字符串的MutableCopy(深拷贝)
[objc] view
plain copy
NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSMutableString *str = [string mutableCopy];
[str appendString:@"1234"];//修改新对象不影响原对象
NSLog(@"str:%@", str);
NSLog(@"string:%@", string);
5.拷贝自定义对象,下面以Student对象为例
a.Student要实现copy,必须实现<NSCopying>协议
b.实现<NSCopying>协议的方法:
- (id)copyWithZone:(NSZone *)zone
Student.h文件
[objc] view
plain copy
@interface Student : NSObject <NSCopying>
// copy代表set方法会release旧对象、copy新对象
// 修改外面的变量,并不会影响到内部的成员变量
// 建议:NSString一般用copy策略,其他对象一般用retain
@property (nonatomic, copy) NSString *name;
+ (id)studentWithName:(NSString *)name;
@end
Student.m文件
[objc] view
plain copy
#import "Student.h"
@implementation Student
+ (id)studentWithName:(NSString *)name {
// 这里最好写[self class]
Student *stu = [[[[self class] alloc] init] autorelease];
stu.name = name;
return stu;
}
- (void)dealloc {
[_name release];
[super dealloc];
}
#pragma mark description方法内部不能打印self,不然会造成死循环
- (NSString *)description {
return [NSString stringWithFormat:@"[name=%@]", _name];
}
#pragma mark copying协议的方法
// 这里创建的副本对象不要求释放
- (id)copyWithZone:(NSZone *)zone {
Student *copy = [[[self class] allocWithZone:zone] init];
// 拷贝名字给副本对象
copy.name = self.name;
return copy;
}
@end
拷贝Student
[objc] view
plain copy
Student *stu1 = [Student studentWithName:@"stu1"];
Student *stu2 = [stu1 copy];
stu2.name = @"stu2";
NSLog(@"stu1:%@", stu1);
NSLog(@"stu2:%@", stu2);
[stu2 release];
.小结:
建议:NSString一般用copy策略,其他对象一般用retain;
只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;
相关文章推荐
- iOS 修改导航栏的返回按钮的内容
- iOS图片设置圆角的三种方式
- IOS总结
- iOS 保持界面流畅的技巧
- iOS 横竖屏控制
- iOS开发之实现毛玻璃效果及图片模糊效果
- iOS字符串操作
- iOS编程修改系统音量
- ios引导页 设定以及 图片尺寸
- iOS7或以后将不能使用MAC地址生成设备的唯一标识
- 定制ios7中的导航栏和状态栏
- iOS文件操作
- 在开发iOS程序时对日期处理的总结(转)
- Android IOS WebRTC 音视频开发总结(六八)-- Google: What's next for WebRTC
- iOS开发-NSData全部API翻译学习
- "Could not find Developer Disk Image"问题,为Xcode 7.3之前版本配置iOS9.3配置包
- iOS临近切换听筒和扬声器
- iOS基础知识—最简单的get与set方法实现
- OC IOS 自定义Log日志 附:常用输出宏
- iOS真机测试推送证书生成