900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:

Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:

时间:2019-04-28 00:45:33

相关推荐

Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:

OC内部:可变对象和不可变对象的深(复制)拷贝问题思考:

不可变对象: 例如NSString对象,因为NSString对象是常量字符串,所以,不可以更改其内容,但是可以修改指向该字符串的指针指向。当对NSString对象做深拷贝时,如果是copy复制方式,其实就是浅复制,只是复制了同一个对象的指针;如果是mutableCopy复制方式,系统会分配一个新的内存空间用来存放复制出来的NSMutableString对象,此时地址是新的,内容是一样的,他们正在被不同的实例变量字符串指针指着。 可变对象: 例如NSMutableString对象,因为NSMutableString对象是可变字符串,所以,可以改变其内容。当NSMutableString对象做深拷贝时,系统会分配一个新的内存空间用来存放复制出来的NSMutableString对象,此时地址是新的,内容是一样的,他们正在被不同的实例变量字符串指针指着。 总结:对于系统的非容器类对象,我们可以认为,如果对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的的。

1:对于不可变对象,copy都是浅复制,即指针复制。mutableCopy 都是Alloc一个新对象返回。

2:对于可变对象,copy和mutableCopy都是Alloc新对象返回。

3:不论是可变还是不可变对象,copy返回的对象都是不可变的,mutableCopy返回的对象都是可变的。

4:容器类对象,不论是可变的还是不可变的,copy,mutableCopy返回的对象里所包含的对象的地址和之前都是一样 的,即容器内对象都是浅拷贝。

一、不可变对象的深复制

1 // Person.h 2 // 测试 3 // 4 // Created by ma c on 15/8/15. 5 // Copyright (c) . All rights reserved. 6 // 7 8 #import <Foundation/Foundation.h> 9 10 @interface Person : NSObject<NSCopying>11 @property(nonatomic,copy)NSString *name;12 -(id)initWithName:(NSString *)name;13 -(void)print;14 @end

1 // Person.m 2 // 测试 3 // 4 // Created by ma c on 15/8/15. 5 // Copyright (c) . All rights reserved. 6 // 7 8 #import "Person.h" 9 10 @implementation Person11 -(id)initWithName:(NSString *)name12 {13self = [super init];14if(self)15{16 _name = [name mutableCopy]; //不可变深复制mutableCopy17 //_name = [name copy];//不可变深复制copy18}19return self;20 }21 -(id)copyWithZone:(NSZone *)zone22 {23return [[Person alloc]initWithName:_name];24 }25 @end

主函数测试

// main.m// 测试//// Created by ma c on 15/8/15.// Copyright (c) . All rights reserved.//#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]){@autoreleasepool {NSMutableString *name = [NSMutableString stringWithString:@"Jobs"]; Person *p1 = [[Person alloc]initWithName:name]; NSLog(@"%@----%p",name,p1.name); Person *p2 = [p1 copy]; NSLog(@"%@----%p",name,p2.name); [name appendString:@"Tom"]; Person *p3 = [[Person alloc]initWithName:name]; NSLog(@"%@----%p",name,p3.name); Person *p4 = [p3 copy]; NSLog(@"%@----%p",name,p4.name); } return 0;}

测试结果如下:

-08-15 22:14:33.544测试[2042:151149] Jobs----0x100206d10

-08-15 22:14:33.545测试[2042:151149] Jobs----0x100300360

-08-15 22:14:33.545测试[2042:151149] JobsTom----0x100300410

-08-15 22:14:33.545测试[2042:151149] JobsTom----0x100400010

Program ended with exit code: 0

以上结果为mutableCopy深复制的结果:复制后一样的内容,可是各自所在的地址值是不同的,说明了系统为新创建的对象开辟了内存,这就是真正意义的深复制。

-08-15 22:15:08.773测试[2050:151390] Jobs----0x100206d10

-08-15 22:15:08.774测试[2050:151390] Jobs----0x100206d10

-08-15 22:15:08.775测试[2050:151390] JobsTom----0x100207810

-08-15 22:15:08.775测试[2050:151390] JobsTom----0x100207810

Program ended with exit code: 0

以上结果为copy深复制结果,可以看出复制后一样的内容,可是它们的地址值是一样,说明了这并不是真正意义的深复制,而是假深复制,即最终结果是只是复制了指针。

二、可变对象的深复制

1 // Person.h 2 // 测试 3 // 4 // Created by ma c on 15/8/15. 5 // Copyright (c) . All rights reserved. 6 // 7 8 #import <Foundation/Foundation.h> 9 10 @interface Person : NSObject<NSCopying>11 @property(nonatomic,copy)NSMutableString *name;12 -(id)initWithName:(NSMutableString *)name;13 -(void)print;14 @end

1 // Person.m 2 // 测试 3 // 4 // Created by ma c on 15/8/15. 5 // Copyright (c) . All rights reserved. 6 // 7 8 #import "Person.h" 9 10 @implementation Person11 -(id)initWithName:(NSMutableString *)name12 {13self = [super init];14if(self)15{16 //_name = [name copy];//可变深复制copy17 _name = [name mutableCopy];//可变深复制mutableCopy18}19return self;20 }21 -(id)copyWithZone:(NSZone *)zone22 {23return [[Person alloc]initWithName:_name];24 }25 @end

主函数测试

1 // main.m 2 // 测试 3 // 4 // Created by ma c on 15/8/15. 5 // Copyright (c) . All rights reserved. 6 // 7 8 #import <Foundation/Foundation.h> 9 #import "Person.h"10 int main(int argc, const char * argv[])11 {12@autoreleasepool13{14 NSMutableString *name = [NSMutableString stringWithString:@"Jobs"];15 16 Person *p1 = [[Person alloc]initWithName:name];17 NSLog(@"%@----%p",name,name);18 NSLog(@"%@----%p",p1.name,p1.name);19 20}21return 0;22 }

测试结果如下:

-08-15 21:54:12.110 测试[1973:145250] Jobs----0x1001002d0-08-15 21:54:12.111 测试[1973:145250] Jobs----0x100106c90Program ended with exit code: 0以上结果为可变对象的复制,采用copy复制时,复制出的内容是一样的,但是它们的地址值是不相同的,所以这是真正意义的深复制。

-08-15 21:56:05.744 测试[1981:145831] Jobs----0x1001147a0-08-15 21:56:05.745 测试[1981:145831] Jobs----0x100114a40Program ended with exit code: 0以上结果为可变对象的复制,采用mutableCopy复制时,复制出的内容也是一样的,但是它们的地址值也是不同的,这也是真正意义的深复制。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。