提问人:Pinxaton 提问时间:4/19/2014 最后编辑:Pinxaton 更新时间:4/19/2014 访问量:248
了解副本和可变副本
understanding copy and mutable copy
问:
请考虑以下几点:
// BaseClass is both NSCopyable and NSMutableCopyable
@interface MyClass : BaseClass {
// a bunch of properties
}
// x is a MyClass* local variable in a method
MyClass *a = [x copy]; // a is a strong reference to an immutable copy?
MyClass *b = [x mutableCopy]; // b is a strong reference to a mutable copy?
问题:
我可以对 a 的 iVar 进行任何更改吗?如果没有,如果我尝试对任何 iVar 进行更改,会发生什么情况?我是否会遇到不确定的行为,例如,有时它有效,有时它不起作用,内存损坏,或者编译器是否完全禁止它?
我可以对 b 的 iVar 进行任何更改吗?
答:
1赞
tia
4/19/2014
#1
简答题
- 是的。没有内存损坏,如果 iVar 可访问,则不会出现编译错误。
- 与 1 相同。
长答案
可变和不可变副本是 Apple 基础类中的核心概念之一,例如 或 。如 NSCopying
协议中所述,实现“不可变与可变”概念的类必须返回 copyWithZone:
的不可变对象。NSString
NSArray
但是,编译器或内存保护不会强制执行对象的不可变性,但类设计者必须设计类以使其在接收消息时返回不可变对象。copy
在你的例子中,实现这种东西的常用方法是使不可变,并使其子类化并使其可变。您的呼叫站点应如下所示:MyClass
MyMutableClass
MyClass *a = [x copy];
MyMutableClass *b = [x mutableCopy];
请注意,实现可变/不可变有时非常乏味,因此请确保您有足够的理由来实现此类功能。
评论
0赞
Pinxaton
4/19/2014
现在假设我正在从 SpriteKit 库中复制一个类似 SKNode 的类,该库实现了 NSCopying,但不实现 NSMutableCopying。当我在 SKNode* 上调用 copy 而不是 mutableCopy 时,鉴于它不实现 NSMutableCopying,我是否假设它返回的对象是可变的?从您上面的解释中我的理解是,除非存在类的可变版本,例如 SKMutableNode,否则我可以假设我可以修改返回的副本?
0赞
tia
4/20/2014
在常见情况下,您可以假设这一点。然而,这实际上取决于实现,因为合约没有说明这种情况的任何内容,例如它可能是深克隆或浅克隆,或者任何东西。我建议,如果文档(例如 SpriteKit 文档)没有阐明方法的性质,那么常识在这里非常有用。NSCopying
copy
评论