mutableCopy使包含的对象可变吗?

时间:2011-12-28 21:59:10

标签: objective-c cocoa nsmutablearray

myArray是NSDictionary对象的NSArray。请问[myArray mutableCopy]是否包含原始NSDictionary对象或NSMutableDictionary副本?是否有一种简单的方法可以使不可变对象图完全可变?

3 个答案:

答案 0 :(得分:7)

如果您不介意大对象图所需的时间,并且实际上想要对象的深层副本,则可以序列化对象图,然后对其进行反序列化。最简单的方法(假设所有对象都是Foundation Collection Objects)是使用NSPropertyListSerialization类。将根对象序列化为数据,然后使用NSPropertyListMutableContainersAndLeaves选项反序列化为可变的根级别数组。您生成的根级可变数组将是一个深层副本,所有容器都是可变的。重要的是要记住,这确实是一个深层复制,所以如果你在另一个容器中改变某些东西,那么这个改变就不会反映在原始对象中。

以下是一个快速代码示例:

// Assumes the root-level object is an array, adjust as necessary
- (NSMutableArray*)deepMutableCopyOfArray:(NSArray*)array error:(NSError**)outError
{
  NSError* error = nil;
  NSData* serializedData = [NSPropertyListSerialization dataWithPropertyList:array format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];
  if( !serializedData ) {
    if( outError ) *outError = error;
    return nil;
  }

  NSMutableArray* mutableCopy = [[NSPropertyListSerialization propertyListWithData:serializedData options:NSPropertyListMutableContainersAndLeaves format:NULL error:&error] retain];
  if( !mutableCopy ) {
    if( outError ) *outError = error;
    return nil;
  }

  return mutableCopy;
}

答案 1 :(得分:2)

可可的副本通常很浅。这意味着它只影响最顶层的对象,在本例中是数组。你最终会得到一个可变数组的不可变字典。没有一个班轮可以像你要问的那样使整个事物变得可变。

答案 2 :(得分:1)

执行此操作的唯一方法是遍历原始数组,创建每个对象的可变副本,并用可变的兄弟替换可变数组中的不可变对象。哇,变异这个词已经失去了所有意义。

NSArray *mutableArray = [originalArray mutableCopy];

for (NSDictionary *dictionary in originalArray)
{
    NSInteger index = [originalArray indexOfObject:dictionary];
    NSMutableDictionary *mutableDictionary = [dictionary mutableCopy];
    [mutableArray replaceObjectAtIndex:index withObject:mutableDictionary];
}

应该很清楚,您可以使用嵌套for循环进一步深入到图形中。根据数组的大小,您可能需要一个自动释放池来控制内存。