copy 和 mutableCopy 如何应用于 NSArray 和 NSMutableArray?
在 NSArray
或 NSMutableArray
上使用时,copy
和 mutableCopy
有什么区别?
这是我的理解;这是正确的吗?
// ** NSArray **
NSArray *myArray_imu = [NSArray arrayWithObjects:@"abc", @"def", nil];
// No copy, increments retain count, result is immutable
NSArray *myArray_imuCopy = [myArray_imu copy];
// Copys object, result is mutable
NSArray *myArray_imuMuta = [myArray_imu mutableCopy];
// Both must be released later
// ** NSMutableArray **
NSMutableArray *myArray_mut = [NSMutableArray arrayWithObjects:@"A", @"B", nil];
// Copys object, result is immutable
NSMutableArray *myArray_mutCopy = [myArray_mut copy];
// Copys object, result is mutable
NSMutableArray *myArray_mutMuta = [myArray_mut mutableCopy];
// Both must be released later
What is the difference between copy
and mutableCopy
when used on either an NSArray
or an NSMutableArray
?
This is my understanding; is it correct?
// ** NSArray **
NSArray *myArray_imu = [NSArray arrayWithObjects:@"abc", @"def", nil];
// No copy, increments retain count, result is immutable
NSArray *myArray_imuCopy = [myArray_imu copy];
// Copys object, result is mutable
NSArray *myArray_imuMuta = [myArray_imu mutableCopy];
// Both must be released later
// ** NSMutableArray **
NSMutableArray *myArray_mut = [NSMutableArray arrayWithObjects:@"A", @"B", nil];
// Copys object, result is immutable
NSMutableArray *myArray_mutCopy = [myArray_mut copy];
// Copys object, result is mutable
NSMutableArray *myArray_mutMuta = [myArray_mut mutableCopy];
// Both must be released later
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
copy
和mutableCopy
是在不同的协议中定义的(分别是NSCopying
和NSMutableCopying
),以及NSArray< /code> 两者都符合。
mutableCopy
是为NSArray
(不仅仅是NSMutableArray
)定义的,它允许您为原始不可变数组创建可变副本:摘要:
mutableCopy
的结果都是可变的。对于数组,结果应该是NSMutableArray
。copy
的结果是可变的!copy
NSMutableArray
可能返回一个NSMutableArray
,因为那是原始类,但是copying 任何任意
NSArray
实例都不会。编辑:根据 Mark Bessey 的回答重新阅读原始代码。当您创建数组的副本时,当然您仍然可以修改原始数组,无论您如何处理该副本。
copy
与mutableCopy
会影响新数组是否可变。编辑 2:修正了我的(错误)假设,即
NSMutableArray -copy
将返回NSMutableArray
。copy
andmutableCopy
are defined in different protocols (NSCopying
andNSMutableCopying
, respectively), andNSArray
conforms to both.mutableCopy
is defined forNSArray
(not justNSMutableArray
) and allows you to make a mutable copy of an originally immutable array:Summary:
mutableCopy
to be mutable, regardless of the original type. In the case of arrays, the result should be anNSMutableArray
.copy
to be mutable!copy
ing anNSMutableArray
may return anNSMutableArray
, since that's the original class, butcopy
ing any arbitraryNSArray
instance would not.Edit: re-read your original code in light of Mark Bessey's answer. When you create a copy of your array, of course you can still modify the original regardless of what you do with the copy.
copy
vsmutableCopy
affects whether the new array is mutable.Edit 2: Fixed my (false) assumption that
NSMutableArray -copy
would return anNSMutableArray
.我认为您一定误解了 copy 和 mutableCopy 的工作原理。在第一个示例中,myArray_COPY 是 myArray 的不可变副本。复制后,您可以操作原始 myArray 的内容,而不影响 myArray_COPY 的内容。
在第二个示例中,您创建了 myArray 的可变副本,这意味着您可以修改数组的任一副本,而不会影响另一个副本。
如果我更改第一个示例以尝试从 myArray_COPY 插入/删除对象,则会失败,正如您所期望的那样。
也许思考一个典型的用例会有所帮助。通常情况下,您可能会编写一个接受
NSArray *
参数的方法,并基本上存储它以供以后使用。你可以这样做:...但是你会遇到一个问题,即可以使用 NSMutableArray 作为参数来调用该方法。创建数组的代码可能会在调用 doStuffLaterWith: 方法和稍后需要使用该值之间对其进行操作。在多线程应用程序中,数组的内容甚至可能在迭代数组时发生更改,这可能会导致一些有趣的错误。
如果您这样做:
...那么副本将在调用该方法时创建数组内容的快照。
I think you must have misinterpreted how copy and mutableCopy work. In your first example, myArray_COPY is an immutable copy of myArray. Having made the copy, you can manipulate the contents of the original myArray, and not affect the contents of myArray_COPY.
In the second example, you create a mutable copy of myArray, which means that you can modify either copy of the array, without affecting the other.
If I change the first example to try to insert/remove objects from myArray_COPY, it fails, just as you'd expect.
Perhaps thinking about a typical use-case would help. It's often the case that you might write a method that takes an
NSArray *
parameter, and basically stores it for later use. You could do this this way:...but then you have the problem that the method can be called with an NSMutableArray as the argument. The code that created the array may manipulate it between when the doStuffLaterWith: method is called, and when you later need to use the value. In a multi-threaded app, the contents of the array could even be changed while you're iterating over it, which can cause some interesting bugs.
If you instead do this:
..then the copy creates a snapshot of the contents of the array at the time the method is called.
“copy”方法返回通过实现 NSCopying 协议 copyWithZone 创建的对象:
如果向 NSString 发送复制消息:
返回值将是一个 NSString (不可变)
mutableCopy 方法返回通过实现 NSMutableCopying 协议的 mutableCopyWithZone 创建的对象:
通过发送:
返回值将会是可变的。
在所有情况下,该对象必须实现该协议,这意味着它将创建新的副本对象并将其返回给您。
对于 NSArray 来说,浅复制和深复制有额外的复杂性。
NSArray 的浅拷贝只会复制对原始数组对象的引用并将它们放入新数组中。
结果是:
也会影响原始数组中索引 0 处的对象。
深层复制实际上会复制数组中包含的各个对象。这是通过向每个单独的对象发送“copyWithZone:”消息来完成的。
编辑以消除我对可变对象复制的错误假设
The "copy" method returns the object created by implementing NSCopying protocols copyWithZone:
If you send NSString a copy message:
The return value will be an NSString (not mutable)
The mutableCopy method returns the object created by implementing NSMutableCopying protocol's mutableCopyWithZone:
By sending:
The return value WILL be mutable.
In all cases, the object must implement the protocol, signifying it will create the new copy object and return it to you.
In the case of NSArray there is an extra level of complexity regarding shallow and deep copying.
A shallow copy of an NSArray will only copy the references to the objects of the original array and place them into the new array.
The result being that:
Will also affect the object at index 0 in the original array.
A deep copy will actually copy the individual objects contained in the array. This done by sending each individual object the "copyWithZone:" message.
Edited to remove my wrong assumption about mutable object copying
将创建
anotherArray
,它是oldArray
的副本,深度为 2 层。如果oldArray
的对象是一个数组。大多数应用中通常都是这种情况。好吧,如果我们需要一个真正的深度复制,我们可以使用,
这将确保所有级别实际上都被复制,并保留每个级别的原始对象的可变性。
罗伯特·克拉伦斯·达尔梅达,
印度班加罗尔。
will create
anotherArray
which is a copy ofoldArray
to 2 levels deep. If an object ofoldArray
is an Array. Which is generally the case in most applications.Well if we need a True Deep Copy we could use,
This would ensure that all levels are actually copied retaining the mutability of the original object at each level.
Robert Clarence D'Almeida,
Bangalore, India.
您正在原始数组上调用 addObject 和 removeObjectAtIndex ,而不是您创建的新副本。调用 copy 与 mutableCopy 只会影响对象的新副本的可变性,而不影响原始对象。
You're calling addObject and removeObjectAtIndex on the original array, rather than the new copy of it you've made. Calling copy vs mutableCopy only effects the mutability of the new copy of the object, not the original object.
简单来说,
复制(在这两种情况下)意味着您获得一个新数组,其中“填充”了对原始数组的对象引用(即在副本中引用相同(原始)对象。
如果将新对象添加到 mutableCopy,则它们是唯一的如果从 mutableCopy 中删除对象,则
在这两种情况下都会将其视为原始数组在创建副本时的快照。
To state it simply,
Copy (in both cases) means that you get a new array "populated" with object references to the original array (i.e. the same (original) objects are referenced in the copies.
If you add new objects to the mutableCopy, then they are unique to the mutableCopy. If you remove objects from the mutableCopy, they are removed from the original array.
Think of the copy in both cases, as a snapshot in time of the original array at the time the copy was created.
假设
B的内容是NSDictionary对象而不是NSMutableDictionary,对吗?
Assume
B's content is NSDictionary object not NSMutableDictionary, is it right?
您必须知道这些复制内容的返回类型,并且在声明将分配给哪个新对象时,返回值必须是不可变或可变的,否则编译器将显示错误。
已复制的对象无法使用新对象进行修改,它们现在完全是两个不同的对象。
You have to know the return type of these copying stuff and while declaring the new object which one will be assigned the return value must be of immutable or mutable one, otherwise compiler will show you error.
The object which has been copied can not be modified using the new one,they are totally two different objects now.