使用NSCopying复制私有实例变量的最佳实践

时间:2010-04-02 15:10:42

标签: cocoa instance-variables nscopying

我可能会遗漏一些明显的东西,但我正在我的一个对象上实现NSCopying。该对象具有未通过getter公开的私有实例变量,因为它们不应在对象外部使用。

copyWithZone:的实现中,我需要alloc / init新实例,还要设置其状态以匹配当前实例。我显然可以从copyWithZone:内部访问当前的私有状态,但我无法将其设置为新对象,因为该状态没有访问器。

是否有一种标准的方法可以保持数据隐私不变?

感谢。

3 个答案:

答案 0 :(得分:8)

首先,你应该总是有吸气剂,即使它们是私人的。您的对象应该只使用访问器访问自己的ivars(除非极少数情况)。这将为您节省大量内存管理的痛苦。

其次,Alex建议使用 - >是一种标准方法,即使这违反了上面的getter规则。该规则有少量例外,副本是其中之一。在这里使用私有的setter仍然是合理的(我过去常常这样做),但我发现由于各种原因使用 - >通常更清洁。

要非常小心,以确保内存管理正确无误。如果您需要致电[super copyWithZone:],那么您还应该了解NSCopyObject()的复杂性及其对您的影响,即使您不自行使用它也是如此。我在"NSCopyObject() considered harmful."

中详细讨论了这个问题

答案 1 :(得分:5)

您可以直接访问副本的实例变量。您使用与结构一起使用的相同指针解​​除引用语法。所以,例如,如果你的课是这样的:

@interface MyCopyableClass : NSObject {
    int anInstanceVariable;
}
@end

你可以这样做:

- (id)copyWithZone:(NSZone *)zone {
    MyCopyableClass *theCopy = [[[self class] allocWithZone:zone] init];
    theCopy->anInstanceVariable = anInstanceVariable;
    return theCopy;
}

答案 2 :(得分:1)

一种选择是创建一个接受私有iVar值的自定义初始值设定项。所以你创建它:

-(id) initWithPropertyOne:(SomeClass *) anObject andPropertyTwo:(SomeClass *) anotherObject;

实例化副本时,只需使用自定义初始化程序。