10

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

在我的实现中copyWithZone:,我需要分配/初始化新实例,还需要设置它的状态以匹配当前实例。我显然可以从内部访问当前私有状态copyWithZone:,但我不能将它设置到新对象中,因为该状态没有访问器。

在保持数据隐私完好无损的同时,是否有解决此问题的标准方法?

谢谢。

4

3 回答 3

8

首先,您应该始终拥有 getter,即使它们是私有的。您的对象应该只使用访问器访问它自己的 ivars(极少数情况下除外)。这将为您节省大量内存管理的痛苦。

其次,Alex 建议使用 -> 是一种标准方法,尽管这违反了上面的 getters 规则。该规则有少数例外,副本就是其中之一。在这里使用私有设置器仍然是合理的(而且我以前专门这样做),但我发现由于各种原因,使用 -> 通常会更干净。

要非常小心地确保您的内存管理正确。如果您需要调用,那么即使您自己不使用它[super copyWithZone:],您也应该阅读它的复杂性以及它对您的影响。NSCopyObject()我在“NSCopyObject() 被认为有害”中详细讨论了这一点。

于 2010-04-02T15:31:19.960 回答
5

您可以直接访问副本的实例变量。您使用与结构相同的指针取消引用语法。因此,例如,如果您的课程是这样的:

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

你可以这样做:

- (id)copyWithZone:(NSZone *)zone {
    MyCopyableClass *theCopy = [[[self class] allocWithZone:zone] init];
    theCopy->anInstanceVariable = anInstanceVariable;
    return theCopy;
}
于 2010-04-02T15:22:53.217 回答
1

一种选择是创建一个接受私有 iVar 值的自定义初始化程序。所以你像这样创建它:

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

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

于 2010-04-02T15:32:26.447 回答