您的位置:首页 > 移动开发 > IOS开发

ios深拷贝,浅拷贝,拷贝自定义对象的简单介绍

2015-03-15 12:06 363 查看
copy语法的目的:改变副本的时候,不会影响到源对象;

深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

拷贝有下面两个方法实现拷贝:

[objc] view
plaincopy





- (id)copy;

- (id)mutableCopy;

要实现copy,必须实现<NSCopying>协议

数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例,其他的同理:

1.不可变字符串调用copy实现拷(浅拷贝)

[objc] view
plaincopy





NSString *string = [[NSString alloc] initWithFormat:@"abcde"];

// copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身

// 源对象计数器会+1

// 在浅拷贝情况下,copy其实就相当于retain

NSString *str = [string copy];

2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)

[objc] view
plaincopy





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
plaincopy





NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];

// 会产生一个新对象,str计数器为1

NSString *str = [string copy];

4.可变字符串的MutableCopy(深拷贝)

[objc] view
plaincopy





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
plaincopy





@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
plaincopy





#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
plaincopy





Student *stu1 = [Student studentWithName:@"stu1"];

Student *stu2 = [stu1 copy];

stu2.name = @"stu2";

NSLog(@"stu1:%@", stu1);

NSLog(@"stu2:%@", stu2);

[stu2 release];

.小结:

建议:NSString一般用copy策略,其他对象一般用retain;

只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: