码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-08-15 21:26:06      阅读:2143      评论:0      收藏:0      [点我收藏+]

标签:

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

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

 

   不可变对象的深复制

 

 1 //  Person.h
 2 //  测试
 3 //
 4 //  Created by ma c on 15/8/15.
 5 //  Copyright (c) 2015年 bjsxt. 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) 2015年 bjsxt. All rights reserved.
 6 //
 7 
 8 #import "Person.h"
 9 
10 @implementation Person
11 -(id)initWithName:(NSString *)name
12 {
13     self = [super init];
14     if(self)
15     {
16         _name = [name mutableCopy]; //不可变深复制mutableCopy
17         //_name = [name copy];//不可变深复制copy
18     }
19     return self;
20 }
21 -(void)print
22 {
23     NSLog(@"%@",self);
24     NSLog(@"name:%@----%p",_name,_name);
25 }
26 -(id)copyWithZone:(NSZone *)zone
27 {
28     return [[Person alloc]initWithName:_name];
29 }
30 @end

    主函数测试

 1 //  main.m
 2 //  测试
 3 //
 4 //  Created by ma c on 15/8/15.
 5 //  Copyright (c) 2015年 bjsxt. All rights reserved.
 6 //
 7 
 8 #import <Foundation/Foundation.h>
 9 #import "Person.h"
10 int main(int argc, const char * argv[])
11 {
12     @autoreleasepool
13     {
14         NSMutableString *name = [NSMutableString stringWithString:@"Jobs"];
15         Person *p1 = [[Person alloc]initWithName:name];
16         [p1 print];
17 
18        
19         Person *p2 = [p1 copy];
20         [p2 print];
21 
22 
23         [name appendString:@"Tom"];
24         Person *p3 = [[Person alloc]initWithName:name];
25         [p3 print];
26 
27 
28         Person *p4 = [p3 copy];
29         [p4 print];
30     }
31     return 0;
32 }

    测试结果如下:

2015-08-15 20:35:58.163 测试[1713:126141] <Person: 0x100206c60>
2015-08-15 20:35:58.164 测试[1713:126141] name:Jobs----0x100206d30
2015-08-15 20:35:58.164 测试[1713:126141] <Person: 0x100300200>
2015-08-15 20:35:58.164 测试[1713:126141] name:Jobs----0x100300210
2015-08-15 20:35:58.165 测试[1713:126141] <Person: 0x1001002d0>
2015-08-15 20:35:58.165 测试[1713:126141] name:JobsTom----0x1001003e0
2015-08-15 20:35:58.165 测试[1713:126141] <Person: 0x100106980>
2015-08-15 20:35:58.165 测试[1713:126141] name:JobsTom----0x100100250
Program ended with exit code: 0


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

 

2015-08-15 20:41:16.156 测试[1724:127122] <Person: 0x100306c40>
2015-08-15 20:41:16.157 测试[1724:127122] name:Jobs----0x100306d10
2015-08-15 20:41:16.157 测试[1724:127122] <Person: 0x10010c8d0>
2015-08-15 20:41:16.157 测试[1724:127122] name:Jobs----0x100306d10
2015-08-15 20:41:16.157 测试[1724:127122] <Person: 0x1002009f0>
2015-08-15 20:41:16.158 测试[1724:127122] name:JobsTom----0x100200a00
2015-08-15 20:41:16.158 测试[1724:127122] <Person: 0x100200a60>
2015-08-15 20:41:16.158 测试[1724:127122] name:JobsTom----0x100200a00
Program ended with exit code: 0

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

 

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

标签:

原文地址:http://www.cnblogs.com/XYQ-208910/p/4733106.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!