2010-04-02 47 views
10

我可能会在这里丢失一些明显的东西,但是我在其中一个对象上实现了NSCopying。该对象具有不通过getter公开的私有实例变量,因为它们不应该在对象之外使用。使用NSCopying复制私有实例变量的最佳做法

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

有没有一个标准的解决方法,同时仍然保持数据隐私完好?

谢谢。

回答

8

首先,你应该始终有干将,即使它们是私有的。你的对象应该只能访问使用访问器的自己的ivars(除了极少数情况)。这将为您节省内存管理带来的巨大痛苦。其次,Alex的使用 - >的建议是一种标准方法,尽管这违反了上面的getters规则。该规则有少数例外,并且副本是其中之一。在这里使用私人设置器仍然是合理的(我以前只是这样做),但是我发现,出于各种原因,使用 - >经常会使用更清洁的设备。

要非常小心地让你的内存管理正确。如果您需要致电[super copyWithZone:],那么您还应该了解NSCopyObject()的复杂性以及它对您的影响,即使您自己不使用它。我已经详细讨论了这个问题"NSCopyObject() considered harmful."

+0

感谢提及私有访问器以及NSCopyObject的风险。 – 2010-04-02 15:40:40

+0

我不确定只读访问器如何帮助内存管理?如果你没有用'assign'或'retain'来使用它,不管你是直接使用getter还是变量都没有区别。 – Hemant 2011-01-20 03:22:05

+0

@Hemant,因为调用者不需要小心该属性目前(或将来)是否只读。这不是调用者的业务,它可能会随着时间而改变,然后您需要搜索不正确的代码。通过坚持简单的规则,错误变得明显。当你说“哦,除非我碰巧知道它现在没问题”,那么你正在为自己的维护问题而烦恼。 – 2011-01-20 19:44:05

5

您可以直接访问副本的实例变量。您可以使用与结构一样的指针解引用语法。因此,举例来说,如果你的类是这样的:

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

你可以这样做:

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

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

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

当你实例化副本,只需使用自定义初始值设定项。

相关问题