使用原始元素的可变副本复制NSArray

Chr*_*ris 11 cocoa objective-c copying nsmutablearray nsarray

我正在一个类中创建一个字典数组.我想将该数组的副本返回给要求它的任何其他对象.传递给其他对象的副本需要在不修改原始对象的情况下进行修改.

所以我在我的类的getter方法中使用以下内容来保存"master"数组:

[[NSMutableArray alloc] initWithArray:masterArray copyItems:YES];
Run Code Online (Sandbox Code Playgroud)

但是,这似乎使所有字典内部不可变.我怎么能避免这个?

我想我在这里遗漏了一些东西.任何帮助都感激不尽!

Bri*_*ter 14

您可以采用的另一种方法是使用CFPropertyListCreateDeepCopy()函数(在CoreFoundation框架中),为mutabilityOption参数传入kCFPropertyListMutableContainers.代码看起来像:

NSMutableArray* originalArray;
NSMutableArray* newArray;

newArray = (NSMutableArray*)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFPropertyListRef)originalArray, kCFPropertyListMutableContainers);
Run Code Online (Sandbox Code Playgroud)

这不仅会创建字典的可变副本,而且还会递归地复制这些字典所包含的任何内容.请注意,这仅在您的字典数组仅包含有效属性列表(数组,数字,日期,数据,字符串和字典)的对象时才有效,因此这可能适用于您的特定情况,也可能不适用.


Jim*_*eia 6

复制数组将创建数组对象的副本,并引用原始内容对象(适当保留.)

根据文档,-initWithArray:copyItems:使用原始数组中的项目副本初始化新数组.此副本是通过发送原始内容对象-copyWithZone:创建的,这将在可变对象的情况下创建不可变副本.

如果您需要不同的行为(即内容对象的可变副本或内容对象的深层副本),您将必须编写自己的便利函数/方法来执行此操作.

  • 更不用说括号后的一个.但是,是的,每次编辑都是迈向社区的一步 - 维基某人的帖子(http://stackoverflow.com/questions/128434/what-are-community-wiki-posts-on-stack-overflow/128436#128436),所以,不要浪费他们"修复"他人的语法,唯一的例外是数字化恢复其他不可读的帖子. (7认同)
  • 那是一个真正无聊的编辑奎因.用原始动画中的逗号来抵消该短语是完全可以接受的.如果你要成为一个语法纳粹,你仍然需要在"ie"之后使用逗号,甚至在括号内. (4认同)

Pet*_*sey 5

一种方法是滥用键值编码发送mutableCopy到每个词典和autorelease每个副本.但这是一个肮脏,肮脏的黑客,所以不要这样做.实际上,你可能不应该首先这样做.

通常,当我看到"词典数组"这个词时,我认为你使用词典作为模型对象的替代品.不要那样做.编写自己的模型类; 当您拥有自己的自定义属性和行为方法时,一切都变得更加容易.(有些事情比其他事情更重要:如果没有合适的模型层,实现AppleScript支持几乎是不可能的.)

一旦你拥有真正的模型对象,就可以NSCopying在它们中实现,而不需要担心mutable和immutable,因为你可能无论如何都不会在真正的模型类中进行可变性区分.(我不了解其他人,但我从未在我的模型类中做过这样的区分.)然后你可以使用现有的NSArray initWithArray:copyItems:方法.