在*.m文件中的@interface关键字

5

我只是想知道这两者之间是否有任何区别:

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property ...
@end

在*.h文件中:
@interface AppDelegate()
@property ...
@end

@implementation AppDelegate

在 *.m 文件中。

我什么时候需要优先选择第一个版本,什么时候使用第二个版本更好?


公共接口与私有类扩展。 - rmaddy
5个回答

5

任何你可以放在.h文件中的内容都可以放在.m文件中。在编译的早期阶段,导入的.h文件的内容会被直接复制到.m文件中,因此基于语句放置位置的语法差异是不存在的。

但是你会注意到,在标签之间存在语法上的差异。

@interface AppDelegate : NSObject <NSApplicationDelegate>

并且。
@interface AppDelegate()

第二种形式是已经描述的接口的一个扩展,而不是一个新的(并且相互冲突的)版本。它放置在 .m 中的事实(这不是必需的 - 它可以放置在 .h 中而不会引发错误)意味着导入 .h 的任何其他模块都不会“看到”它,使其“私有”(就像 Objective-C 中的任何东西一样)。

为什么在 *.m 文件的 @implementation 部分声明 @property 以使其私有化是不可能的(就像我可以声明私有变量一样)?为什么我需要使用 @interface 部分来声明私有属性?这个限制有任何逻辑吗? - ceth
1
@demas -- 这就是语言规范的方式。从简单性的角度来看,这对编译器编写者可能是有意义的。 - Hot Licks

4

公有 vs. 私有

基本上,.h 文件是你的 公有 头文件,而你的 .m 文件是你的 实现私有)。

无论你在.m中的@interface中放置什么内容都将是私有(类扩展等),而你在.h中的@interface公共的

如果我要通过segue传递信息给UIViewController,或者需要访问某个对象中的数据,我会把我的@properties放在.h中。否则,我就把所有东西都放在私有类扩展中(.m)。不过,你也可以只在.h文件中使用你的@properties


为什么在 *.m 文件的 @implementation 部分声明 @property 以使其成为私有属性是不可能的(就像我可以声明私有变量一样)?为什么需要使用 @interface 部分来声明私有属性? - ceth
2
@demas,通常这些标记被用来通过其他工具(如测试套件等)提取有用的信息。这些规则帮助它们识别在一个类中哪里查找其属性,仅此而已。 - Nirav Bhatt
就像Nirav所说的那样,@interface是你告诉类有哪些属性的地方。实现是你实现方法而不是定义属性的地方。 - Nate Lee

2
代码如下:
@interface AppDelegate()
@property ...
@end

创建一个私有类扩展,不能从类实现文件外部看到,这使其成为“private”,与头文件中的“public”不同。
由于Objective-C的动态特性,一旦抑制了编译器警告,仍然可以从其他类调用私有属性。
还可用于声明私有方法,我将它们前缀添加“_”以区别于公共方法,尽管没有这个要求。
@interface AppDelegate()
- (BOOL)_doCoolThing;
@end

您甚至不必声明私有方法,因为编译器只需要定义就可以正常工作,但是我总是同时声明和定义它们。


为什么在 *.m 文件的 @implementation 部分声明 @property 以使其成为私有属性是不可能的(就像我可以声明私有变量一样)?为什么我需要使用 @interface 部分来声明私有属性? - ceth
由于@property声明只能出现在@interface部分而不是@implementation部分,因此如果您希望添加属性到现有属性中,则需要使用类扩展。 - Droppy
"小"细节。它在.m文件中的事实使类扩展变为“私有”。与实际字节模式无关。 - Hot Licks

2

一般来说,你可以在头文件(.h)中使用@interface声明公共属性和方法,这些属性和方法对导入该类的其他类可见。

在实现文件(.m)中使用@interface声明私有属性和方法,这些属性和方法仅在该类内部可见,并且不能被项目中的其他类使用或访问。


为什么在 *.m 文件的 @implementation 部分声明 @property 以使其成为私有属性是不可能的(就像我可以声明私有变量一样)?为什么我需要使用 @interface 部分来声明私有属性? - ceth
我想这只是 objective-c 的定义方式。有一次,我使用了一个私有属性,因为我想从同一类的另一个实例中访问它的值,但我不希望其他类的实例能够看到该属性。 - Thomas C. G. de Vilhena

1
你的代码与第一种变体之间的区别在于,你使用了扩展(以下所有方法仅供 @implementation 使用)。
在 .m 文件中。
@interface ClassName() {
//methods here
}
@end
@implementation ClassName
//method implementation from ClassName() and from .h file for ClassName
@end

在第二个类实现中,你在.h文件中声明的所有方法都像公共方法一样。
有关扩展的更多详细信息,请查看此处
有关类的更多信息,请查看此处
有关属性的信息,请查看此处

为什么在 *.m 文件的 @implementation 部分声明 @property 以使其成为私有属性是不可能的(就像我可以声明私有变量一样)?为什么需要使用 @interface 部分来声明私有属性? - ceth
1
在Objective C中,没有像“private”或“public”这样的东西,你声明的所有方法默认都是“public”的。如果你想隐藏一些东西,你可以在实现文件中使用属性声明(但是这个属性只能在该文件中使用)。关于属性的更多信息,请查看这里 - https://dev59.com/4W035IYBdhLWcg3wErvM - hbk
1
@Kirill - 实际上,“private”属性/方法可以在.m之外使用,如果用户创建了适当的虚拟声明。 - Hot Licks

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