mutableCopy 是否使包含的对象可变?

发布于 2024-12-23 03:56:31 字数 136 浏览 2 评论 0原文

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

myArray is an NSArray of NSDictionary objects. Will [myArray mutableCopy] contain the original NSDictionary objects or NSMutableDictionary copies? Is there a simple way to make an immutable object graph completely mutable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半山落雨半山空 2024-12-30 03:56:31

如果您不介意大型对象图所需的时间,并且您实际上想要对象的深层副本,则可以序列化对象图,然后反序列化它。最简单的方法(假设所有对象都是 Foundation Collection 对象)是使用 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;
}

If you don't mind the amount of time required for a large object graph and you actually want deep copies of objects, you could serialize your object graph and then deserialize it. The easiest way to do this (assuming all your objects are Foundation Collection Objects) is to use the NSPropertyListSerialization class. Serialize your root object to data, then deserialize to your mutable root-level array using the NSPropertyListMutableContainersAndLeaves option. Your resulting root-level mutable array will be a deep-copy and all containers will be mutable. It's important to remember that this really will be a deep-copy, so if you change something in another container, that change won't be reflected in the original objects.

Here is a quick code example:

// 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;
}
心是晴朗的。 2024-12-30 03:56:31

Cocoa 中的副本通常是浅的。这意味着它只影响最顶层的对象,在本例中是数组。你最终会得到一个由不可变字典组成的可变数组。没有一个衬里可以使整个事情像您所要求的那样可变。

Copies in Cocoa are generally shallow. This means that it only affects the top most object, in this case the array. You'll end up with a mutable array of immutable dictionaries. There is no one liner to make the entire thing mutable like you're asking.

深府石板幽径 2024-12-30 03:56:31

执行此操作的唯一方法是迭代原始数组,创建每个对象的可变副本,并将可变数组中的不可变对象替换为其可变兄弟。哎呀,可变这个词已经失去了所有的意义。

NSArray *mutableArray = [originalArray mutableCopy];

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

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

The only way to do this is to iterate through the original array, create mutable copies of each object and replace the immutable objects in the mutable array with their mutable brethren. Whew, the word mutable has lost all meaning.

NSArray *mutableArray = [originalArray mutableCopy];

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

It should be clear that you can work down even further into the graph with nested for loops. Depending on the size of the array, you may require an autorelease pool to keep memory in check.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文