我可能会遗漏一些明显的东西,但我正在我的一个对象上实现NSCopying。该对象具有未通过getter公开的私有实例变量,因为它们不应在对象外部使用。
在copyWithZone:
的实现中,我需要alloc / init新实例,还要设置其状态以匹配当前实例。我显然可以从copyWithZone:
内部访问当前的私有状态,但我无法将其设置为新对象,因为该状态没有访问器。
是否有一种标准的方法可以保持数据隐私不变?
感谢。
答案 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;
实例化副本时,只需使用自定义初始化程序。