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 

首选方法是什么,为什么?我错过了任何其他方法吗?

4

3 回答 3

9

我的偏好是#3:

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

它允许您干净地抽象并最大限度地减少依赖关系。

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

抽象也是一个巨大的优势——私有是默认设置,你没有理由偏离它,也没有理由将内部结构暴露给其他人。这很好地隐藏了这一切,同时确保不损害类型安全。大优点:您还可以轻松地在对象中声明 C++ 值,而无需将每个人都暴露给所有 C++ 库的依赖项——不是 PIMPL,不是全局范围内的结构,不是 *void**,而是正确的。这是一个很棒的编译防火墙。如果您曾参与过大型 C 或 C++ 项目,您可能会很高兴。

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

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

// MyClass.m
...
@interface MONClass ()
@property (nonatomic, copy) NSString * string;
@end
于 2012-08-23T21:19:21.730 回答
3

您几乎按照添加到 Objective-C 的时间顺序方便地列出了它们。

我认为这主要是一个风格问题,但我会说 99% 的时间:

(1) 不要将它们放在 .h 文件中,因为 .h 文件实际上是发布的接口,没有理由发布实现细节;

(2)以避免无关语法为由,将它们放在类扩展中@implementation而不是类扩展中。@interface你总是会有一个实现,你可能没有类扩展。

于 2012-08-23T21:20:42.197 回答
0

如果有人想在不编辑的情况下使用 MyClass,他们会快速阅读头文件以了解它是如何工作的。由于它们不关心您的私有变量,因此最好将它们放在标题之外。

如果您想要私有属性或私有实现的协议,则需要在.m文件中使用类延续。

@interface MyClass () <SomeKindOfDelegate>
@property id someProperty;
@end

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

当你这样做的时候,你也可以把你的成员变量也放在延续中。

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

@implementation MyClass
@synthesize someProperty;
- (void)someKindOfDelegateMessage:(id)sender { }
@end
于 2012-08-23T21:32:33.170 回答