標籤:
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 Person11 -(id)initWithName:(NSString *)name12 {13 self = [super init];14 if(self)15 {16 _name = [name mutableCopy]; //不可變深複製mutableCopy17 //_name = [name copy];//不可變深複製copy18 }19 return self;20 }21 -(void)print22 {23 NSLog(@"%@",self);24 NSLog(@"name:%@----%p",_name,_name);25 }26 -(id)copyWithZone:(NSZone *)zone27 {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 @autoreleasepool13 {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----0x100206d302015-08-15 20:35:58.164 測試[1713:126141] <Person: 0x100300200>2015-08-15 20:35:58.164 測試[1713:126141] name:Jobs----0x1003002102015-08-15 20:35:58.165 測試[1713:126141] <Person: 0x1001002d0>2015-08-15 20:35:58.165 測試[1713:126141] name:JobsTom----0x1001003e02015-08-15 20:35:58.165 測試[1713:126141] <Person: 0x100106980>2015-08-15 20:35:58.165 測試[1713:126141] name:JobsTom----0x100100250Program 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----0x100306d102015-08-15 20:41:16.157 測試[1724:127122] <Person: 0x10010c8d0>2015-08-15 20:41:16.157 測試[1724:127122] name:Jobs----0x100306d102015-08-15 20:41:16.157 測試[1724:127122] <Person: 0x1002009f0>2015-08-15 20:41:16.158 測試[1724:127122] name:JobsTom----0x100200a002015-08-15 20:41:16.158 測試[1724:127122] <Person: 0x100200a60>2015-08-15 20:41:16.158 測試[1724:127122] name:JobsTom----0x100200a00Program ended with exit code: 0以上結果為copy深複製結果,可以看出複製後一樣的內容,可是它們的地址值是一樣,說明了這並不是真正意義的深複製,而是假深複製,即最終結果是只是複製了指標。
Objective-C:OC內部可變對象和不可變對象的深(複製)拷貝問題思考: