我可能在这里遗漏了一些明显的东西,但我正在我的一个对象上实现 NSCopying。该对象具有不通过 getter 公开的私有实例变量,因为它们不应在对象外部使用。
在我的实现中copyWithZone:
,我需要分配/初始化新实例,还需要设置它的状态以匹配当前实例。我显然可以从内部访问当前私有状态copyWithZone:
,但我不能将它设置到新对象中,因为该状态没有访问器。
在保持数据隐私完好无损的同时,是否有解决此问题的标准方法?
谢谢。
我可能在这里遗漏了一些明显的东西,但我正在我的一个对象上实现 NSCopying。该对象具有不通过 getter 公开的私有实例变量,因为它们不应在对象外部使用。
在我的实现中copyWithZone:
,我需要分配/初始化新实例,还需要设置它的状态以匹配当前实例。我显然可以从内部访问当前私有状态copyWithZone:
,但我不能将它设置到新对象中,因为该状态没有访问器。
在保持数据隐私完好无损的同时,是否有解决此问题的标准方法?
谢谢。
首先,您应该始终拥有 getter,即使它们是私有的。您的对象应该只使用访问器访问它自己的 ivars(极少数情况下除外)。这将为您节省大量内存管理的痛苦。
其次,Alex 建议使用 -> 是一种标准方法,尽管这违反了上面的 getters 规则。该规则有少数例外,副本就是其中之一。在这里使用私有设置器仍然是合理的(而且我以前专门这样做),但我发现由于各种原因,使用 -> 通常会更干净。
要非常小心地确保您的内存管理正确。如果您需要调用,那么即使您自己不使用它[super copyWithZone:]
,您也应该阅读它的复杂性以及它对您的影响。NSCopyObject()
我在“NSCopyObject() 被认为有害”中详细讨论了这一点。
您可以直接访问副本的实例变量。您使用与结构相同的指针取消引用语法。因此,例如,如果您的课程是这样的:
@interface MyCopyableClass : NSObject {
int anInstanceVariable;
}
@end
你可以这样做:
- (id)copyWithZone:(NSZone *)zone {
MyCopyableClass *theCopy = [[[self class] allocWithZone:zone] init];
theCopy->anInstanceVariable = anInstanceVariable;
return theCopy;
}
一种选择是创建一个接受私有 iVar 值的自定义初始化程序。所以你像这样创建它:
-(id) initWithPropertyOne:(SomeClass *) anObject andPropertyTwo:(SomeClass *) anotherObject;
实例化副本时,只需使用自定义初始化程序。