在先前的博文当中 我们 试着复制 包含可修改字符串的数组物件。你 也看到了 什么 叫做 所谓的浅层复制,那 就是 数组物件所包含的字符串本身 并没有被复制,被复制了的 仅仅 是 数组物件所包含的字符串的地址。
我们 可以利用 基础框架的归档功能 对物件 进行深层复制。比如 在下面的程序当中 我们 把 数组物件dataArray 复制到了 dataArray2。我们 先将 数组物件dataArray 归档 并且 写入 数据缓冲区,然后 将 缓冲区中的数据 解档,并且 将 解档后的物件之地址 存储 在变量dataArray2当中。归档 和 解档的过程 都发生 在内存当中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSString.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSArray.h> int main(int argc,const char *argv[]) { NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init]; NSData *data; NSMutableArray *dataArray=[NSMutableArray arrayWithObjects: [NSMutableString stringWithString:@"one"], [NSMutableString stringWithString:@"two"], [NSMutableString stringWithString:@"three"], nil]; NSMutableArray *dataArray2; NSMutableString *mutableString; data=[NSKeyedArchiver archivedDataWithRootObject:dataArray]; dataArray2=[NSKeyedUnarchiver unarchiveObjectWithData:data]; mutableString=[dataArray2 objectAtIndex:0]; [mutableString appendString:@"ONE"]; NSLog(@"dataArray:"); for(NSString *element in dataArray) { NSLog(@" %@",element); } NSLog(@"dataArray2:"); for(NSString *element in dataArray2) { NSLog(@" %@",element); } [pool drain]; return 0; } |
运行 这个程序过后,可以得到 这样的结果:
|
2012-06-13 11:21:00.605 Sample[816:707] dataArray:
2012-06-13 11:21:00.606 Sample[816:707] one
2012-06-13 11:21:00.611 Sample[816:707] two
2012-06-13 11:21:00.612 Sample[816:707] three
2012-06-13 11:21:00.613 Sample[816:707] dataArray2:
2012-06-13 11:21:00.613 Sample[816:707] oneONE
2012-06-13 11:21:00.613 Sample[816:707] two
2012-06-13 11:21:00.614 Sample[816:707] three
|
从程序的运行结果 可以看出 改变 dataArray2中第一个元素的内容 并不会改变 dataArray中第一个元素的内容。这 是 因为 在归档 和 解档的过程当中,数组物件dataArray中每个字符串 都产生了 一个复制品,而 不仅仅只是 复制了 地址而已。
程序中的
| data=[NSKeyedArchiver archivedDataWithRootObject:dataArray]; dataArray2=[NSKeyedUnarchiver unarchiveObjectWithData:data]; |
这两行语句 先将 数组物件dataArray 归档,写入 缓冲区data,然后 将 缓冲区data中的数据 解档,解档后的物件地址 存储 在变量dataArray2当中。
我们 应该避免 将 第二行语句中的data 直接 替换成 [NSKeyedArchiver archivedDataWithRootObject:dataArray],就像 这样:
|
dataArray2=[NSKeyedUnarchiverunarchiveObjectWithData:[NSKeyedArchiverarchivedDataWithRootObject:dataArray]];
|