我在中看到,-copy总是返回一个不可变的对象,-mutableCopy总是返回一个可变的对象:
重要的是要知道,对可变对象调用
-copy会返回不可变的版本。如果要复制可变对象并在新版本中保持可更改性,则必须在原始版本上调用-mutableCopy。但是,这是有用的,因为如果您想“冻结”一个可变对象,只需在它上调用-copy即可。
所以我有这样的东西:
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
NSLog( @"%@", [req className] ); // NSMutableURLRequest
NSLog( @"%@", [[req copy] className] ); // NSMutableURLRequest
NSLog( @"%@", [[req mutableCopy] className] ); // NSMutableURLRequest根据这个previous answer
,您不能依赖复制的结果是可变的!复制
NSMutableArray可能会返回一个NSMutableArray,因为这是原始类,但是复制任何任意NSArray实例都不会。
这似乎在某种程度上孤立于NSURLRequest,因为NSArray的作用与预期的一样:
NSArray *arr = [[NSMutableArray alloc] init];
NSLog( @"%@", [arr className] ); // __NSArrayM
NSLog( @"%@", [[arr copy] className] ); // __NSAraryI
NSLog( @"%@", [[array mutableCopy] className] ); // __NSArrayM所以..。
-copy何时返回不可变对象(如预期的那样),以及何时返回可变对象?发布于 2011-08-27 04:00:57
我认为你已经发现了文档和现实之间的巨大裂痕。
NSCopying协议文档声称:
如果考虑“不可变的还是可变的”适用于接收对象,则返回的副本是不可变的;否则,副本的确切性质由类决定。
但在某些情况下,这显然是错误的,正如您在示例中所展示的那样(我已经通过文档页面向他们发送了有关这方面的反馈)。
但是(第二)在我看来,其实并不重要,你也不应该在意。
-copy的要点是,它将返回一个可以使用的对象,保证它将独立于原始对象运行。这意味着,如果您有一个可变对象,-copy它,并更改原始对象,副本将不会看到效果。(在某些情况下,我认为这意味着-copy可以被优化为什么都不做,因为如果对象是不可变的,那么它一开始就不能更改。我可能弄错了。(我现在想知道这对字典键意味着什么,但这是一个单独的主题.)
正如您已经看到的,在某些情况下,新对象实际上可能是一个可变的类(即使文档告诉我们它不会)。但是,只要你不依赖于它是可变的(你为什么要这么做?),这并不重要。
你应该怎么做呢?总是把的结果当作不变的,就这样简单。
发布于 2011-08-27 04:18:43
1) -copy何时返回不可变对象(如预期的那样)以及何时返回可变对象?
你应该始终把它看作是不变的变体。不应使用返回类型的可变接口。除了优化,答案不应该重要,应该被视为一个实现细节,除非有文档记录。
显而易见的情况是:由于许多原因,objc类集群和类设计可能很复杂。返回可变副本可能只是为了方便。
2)如何获得拒绝“冻结”的可变对象的“冻结”副本的预期效果?
使用不可变类的复制构造函数是一种很好的方法(类似于St3fan的答案)。就像copy一样,这不是一个保证。
我能想到的唯一原因是,您希望执行此行为是为了性能或强制执行受限的接口(除非它是学术性的)。如果您想要性能或受限制的接口,那么您可以简单地封装一个类型的实例,该实例在创建时复制,并且只公开不可变的接口。然后通过retain实现复制(如果这是您的意图)。
或者,您可以编写自己的子类并实现自己的副本变体。
最后的解决办法:许多可可变/不变类纯粹是接口--如果需要确保特定行为,您可以编写自己的子类--但这是非常不寻常的。
也许更好地描述为什么要强制执行这一点是很好的--现有的实现对绝大多数开发人员/使用来说都很好。
发布于 2011-08-27 03:03:37
请记住,没有一个copy实现--每个类都实现自己的。而且,众所周知,在spots中,目标C运行时的实现有点“松懈”。因此,我认为我们可以说,大多数情况下,copy返回一个不可变的版本,但也存在一些例外。
(顺便说一句,这是做什么的:
NSArray *arr = [[NSMutable array] init];?)
https://stackoverflow.com/questions/7212268
复制相似问题