为什么在 @implementation 上面有 @interface?

38

我想知道为什么有两个 @interface。一个在 class.h 文件中,另一个在 class.m 文件中。例如:

TestTableViewController.h

#import <UIKit/UIKit.h>

@interface TestTableViewController : UITableViewController

@end

我发现 (自动生成的) class.m:

#import "TestTableViewController.h"

@interface TestTableViewController ()

@end

@implementation TestTableViewController

... methods delegated from UITable delegates

@end

我的问题是,@interface TestTableViewController ().m文件中是什么意思。它为什么存在?我需要它吗?

提前感谢!


4个回答

56
第二个@interface指令在实现文件(.m)中--你可以从中推断出它是用来声明一些类创建者不想暴露给类用户的东西。这通常意味着私有和/或内部方法和属性。还要注意,有两种方法可以做到这一点。其中一种(你在这里看到的)被称为"类扩展",它由一对空括号表示:
@interface MyClass ()

这个特别重要,因为您可以使用它向类添加额外的实例变量。

第二个被称为“分类”,由非空括号对表示,括号内包含分类名称,如下所示:

@interface MyClass (CategoryName)

它也用于扩展类。使用分类无法向类添加实例变量,但是您可以为同一类添加多个分类,这就是为什么它主要用于扩展系统/框架类,因为您没有源代码 - 因此,在这种意义上,分类正好相反于类扩展。


3
第二个“接口”定义了“TestTableViewController”类的扩展,在仅导入h文件的情况下对外不可见。这是在Objective C中创建私有方法的实际做法。

不,它不是一个类别,而是一个类扩展。-1。 - user529758
1
不太友好的是-1..类别和扩展之间的区别主要是语义上的:扩展基本上是一个匿名类别,需要在类的主要实现块中实现它。因此,在第二个“接口”块的括号中设置名称,将有效地创建一个类别而不是扩展... - dcoder

2

TestTableViewController.h文件中的接口是类扩展的声明。有两个圆括号表示这一点。语法与编写类别的语法相同。但在这种情况下,它用于声明作者不想在头文件中公开的某些私有方法。

正常的类别接口如下所示:

@interface TestTableViewController (Your_Category_Name)
- (void)doSomething;
@end

对应的实现:

@implementation TestTableViewController (Your_Category_Name)
-(void)doSomething {
// Does something...
}
@end

在您的示例中没有指定类别名称,因此它只是扩展了类并且您可以在正常实现中实现该方法。
通常,这种技术用于“隐藏”方法。它们未在头文件中声明,并且如果您仅导入.h文件,则不可见。

除了声明私有方法和对代码进行分类,使用类别还有其他用途吗? - Matej
谢谢你告诉我。我不知道这被称为类扩展。直到现在,我一直把它想象成一个类别。我会修复它的。 - Sandro Meier
即使没有名字,那也不是在扩展类吗?那我们怎么添加实例变量呢? - mfaani
你需要使用ObjC运行时。看一下这个答案:https://dev59.com/yGvXa4cB1Zd3GeqPMsl3#13757149 - Sandro Meier

2

在这里,您可以声明仅想在类中使用但不想向其他类公开的私有方法和属性。


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