iva*_*ble 117 cocoa cocoa-touch objective-c deep-copy nsarray
是否有任何内置功能可以让我深层复制NSMutableArray?
我环顾四周,有些人说[aMutableArray copyWithZone:nil]是深刻的副本.但我试过,它似乎是一个浅薄的副本.
现在我用for循环手动执行复制:
//deep copy a 9*9 mutable array to a passed-in reference array
-deepMuCopy : (NSMutableArray*) array
toNewArray : (NSMutableArray*) arrayNew {
[arrayNew removeAllObjects];//ensure it's clean
for (int y = 0; y<9; y++) {
[arrayNew addObject:[NSMutableArray new]];
for (int x = 0; x<9; x++) {
[[arrayNew objectAtIndex:y] addObject:[NSMutableArray new]];
NSMutableArray *aDomain = [[array objectAtIndex:y] objectAtIndex:x];
for (int i = 0; i<[aDomain count]; i++) {
//copy object by object
NSNumber* n = [NSNumber numberWithInt:[[aDomain objectAtIndex:i] intValue]];
[[[arrayNew objectAtIndex:y] objectAtIndex:x] addObject:n];
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我想要一个更清洁,更简洁的解决方案.
Fra*_* P. 207
正如Apple文档所述,
如果您只需要一个级别深的副本,您可以明确地要求一个...
Run Code Online (Sandbox Code Playgroud)NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];
上面的代码创建了一个新数组,其成员是旧数组成员的浅表副本.
请注意,如果您需要深度复制整个嵌套数据结构 - 链接的Apple文档称之为"真正的深层副本" - 那么这种方法是不够的 - 请参阅此处的其他答案.
And*_*ant 60
我知道轻松做到这一点的唯一方法是归档,然后立即取消归档你的数组.这感觉有点像黑客,但实际上在Apple文档中明确建议复制集合,其中指出:
如果您需要真正的深层副本,例如当您拥有阵列数组时,只要内容全部符合NSCoding协议,您就可以归档然后取消归档该集合.清单3显示了这种技术的一个例子.
清单3真正的深层副本
Run Code Online (Sandbox Code Playgroud)NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];
问题是您的对象必须支持NSCoding接口,因为这将用于存储/加载数据.
let trueDeepCopyArray = NSKeyedUnarchiver.unarchiveObjectWithData(
NSKeyedArchiver.archivedDataWithRootObject(oldArray))
Run Code Online (Sandbox Code Playgroud)
Cam*_*mer 32
这是因为调用与使用默认区域进行复制copy相同copyWithZone:NULL.该copy调用不会导致深层复制.在大多数情况下,它会给你一个浅的副本,但无论如何它取决于类.有关详细讨论,我建议Apple Developer站点上的Collections Programming Topics.
NSArray *deepCopyArray = [[NSArray alloc] initWithArray:someArray copyItems:YES];
Run Code Online (Sandbox Code Playgroud)
NSCoding 是Apple推荐的提供深层复制的方式对于真正的深层副本(数组),您将需要NSCoding并归档/取消归档对象:
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
Run Code Online (Sandbox Code Playgroud)
对于Dictonary
NSMutableDictionary *newCopyDict = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)objDict, kCFPropertyListMutableContainers);
对于数组
NSMutableArray *myMutableArray = (NSMutableArray *)CFPropertyListCreateDeepCopy(NULL, arrData, kCFPropertyListMutableContainersAndLeaves);
不,框架中没有为此内置任何东西。Cocoa 集合支持浅拷贝(使用 thecopy或 thearrayWithArray:方法),但甚至不谈论深拷贝概念。
这是因为“深拷贝”开始变得难以定义,因为您的集合的内容开始包括您自己的自定义对象。难道“深拷贝”的意思是每一个对象图中的对象是一个独特的相对于基准的每个对象在原来的对象图?
如果有一些假设的NSDeepCopying协议,您可以设置它并在所有对象中做出决定,但不幸的是没有。如果您控制了图中的大部分对象,您可以自己创建此协议并实现它,但您需要根据需要向 Foundation 类添加一个类别。
@AndrewGrant 的回答表明使用键控归档/取消归档对于任意对象来说是一种性能不佳但正确且干净的方法。本书甚至到此为止,因此建议为所有对象添加一个类别,以支持深度复制。
| 归档时间: |
|
| 查看次数: |
79158 次 |
| 最近记录: |