Objective-C中实现私有成员的不同方式比较

12

我来自C++/Java世界,在那里如何创建私有成员很明显。然而,我在Objective C中看到了几种方法,并希望听听它们的优缺点。

1)在.h文件中声明为@private

@interface MyClass : NSObject
{
    @private
    int someMember;  
}
@end

2) 在.m文件中的接口内声明它们。

@interface MyClass() {
    int someMember;  
}
@end

@implementation MyClass
@end

3)在实现中声明它们。

@implementation MyClass {
     int someMember;  
}
@end 

什么是首选方法,为什么?我有忽略了其他方法吗?


我希望你没有误解,在Objective-C中任何私有字段方案都不能真正保护字段免受恶意访问。 - Hot Licks
是的。我了解在Objective-C中你可以在运行时访问所有内容。 - Victor Ronin
3个回答

9

我的偏好是#3:

// MyClass.m
...
@implementation MyClass {
     int someMember;
}
@end

它允许您干净地抽象出来,最小化依赖关系。

由于每个objc对象都是动态分配的,并且物理上的依赖性很小,因此您可以拥有最快的构建时间和最丰富的对象表示,同时最小化编译开销(例如最小化#import和物理依赖性)。

抽象也是一个巨大的优点——私有是默认值,很少有理由偏离这一点,也很少有理由将内部暴露给其他人。这样可以很好地隐藏所有内容,同时确保类型安全不受影响。另外一个好处是:您还可以轻松声明C++值,而无需将所有C++库的依赖项暴露给所有人——不是PIMPL,不是全局范围内的结构体,也不是*void**,而是一个适当的。这是一个很好的编译防火墙。如果您曾经参与过大型C或C++项目的开发,您可能会感到高兴。

当然,如选项#2中所示声明ivars会带来所有这些优点。因此,它基本上取决于您喜欢在何处以及如何查看变量。 ivar声明是具体的,而属性可能是抽象的——所以我倾向于将具体与具体分组和接口与接口分组,但无论哪种方式;#2或#3都是理想的,除非您需要向后兼容。

如果您想要(伪)私有属性,请在类延续中声明它们:

// MyClass.m
...
@interface MONClass ()
@property (nonatomic, copy) NSString * string;
@end

我的偏好也是第3个选项。您知道在子类中是否可以访问它们吗? - Stoff81
@justin这个适用于非基本类型(如int),而是像AVCaptureDevice这样的类的成员吗? - Bhargav
@Bhargav 是的。即使对于这些成员,ARC也会启动。 - justin

3
您很贴心地将它们几乎按照Objective-C添加的时间顺序列出来。
我认为这主要是一个风格问题,但我会说99%的情况下:
(1)不要将它们放在.h文件中,因为.h文件实际上是公开接口,没有理由公开实现细节;
(2)将它们放在@implementation中,而不是在@interface类扩展中,以避免不必要的语法。您总是会有一个实现,而可能没有类扩展。

0
如果有人想使用 MyClass 而无需编辑它,他们会快速阅读头文件来了解它的工作原理。既然他们不关心你的私有变量,最好将它们保留在头文件之外。
如果你想要私有属性或私有实现协议,需要在 .m 文件中使用类延续。
@interface MyClass () <SomeKindOfDelegate>
@property id someProperty;
@end

@implementation MyClass
@synthesize someProperty;
- (void)someKindOfDelegateMessage:(id)sender { }
@end

当你完成这个操作时,最好也将成员变量放在 continuation 中。

@interface MyClass () <SomeKindOfDelegate>
{
    int someMember;
}
@property id someProperty;
@end

@implementation MyClass
@synthesize someProperty;
- (void)someKindOfDelegateMessage:(id)sender { }
@end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接