为什么在接口中声明Objective-C实例变量?

时间:2010-06-14 20:50:24

标签: objective-c

我刚刚进入Objective-C(Java是我的主要OO语言)。

在界面而不是类中定义对象的实例变量似乎很奇怪。我已经习惯了一个接口是一个公共API定义,除了方法签名之外什么都没有(这里没有计算常量)。

是否有某种原因在接口中定义了状态(即使它是私有的),并且在类中定义了行为。看起来很奇怪,因为对象是状态+行为,定义将被分成两个不同的位置。

某种方式是设计优势吗?您只是在Objective-C中被迫处理的后方问题的痛苦?一个非问题,只是不同?关于为什么这样做的任何背景?

或者你可以把对象状态放在一个类中,我还没有在我的书中找到那个部分吗?

2 个答案:

答案 0 :(得分:12)

<强>更新

下面的答案是在实现声明实例中的实例变量的语言功能之前编写的。问题的前提现在已不再有效。正如FireLizzard所说,@interface中不需要公开任何内容。


这是一个遗留问题,即Objective-C起源于构建于C之上的相当薄的层.C方式是定义模块的接口(不要与Java interface混淆)头文件,并在每个编译单元中包含它。它类似于将声明自动复制粘贴到每个编译文件的顶部。如果这看起来很原始,那是因为它是,但C是一个40岁的语言。

您必须在接口中定义实例变量 - 甚至是私有变量 - 因为Objective-C对象是作为C结构实现的,C结构本身只是内存块和该块中的命名偏移量。表示每个类的对象的结构必须包含超类实例变量的空间,因此子类至少需要知道表示超类的C结构的大小以及公共和受保护的实例变量偏移量。遗憾的是,这意味着所有实例变量甚至是私有变量都必须作为外部接口的一部分公开。* C ++其他OO版本的C由于同样的原因而遭受同样的问题。

要记下所有方法签名两次会有点痛苦,但你已经习惯了。

*对于64位运行时,您不再需要在@interface中为合成访问器声明ivars,但由于所有方法都是公共的,它仍然意味着将内部状态暴露给外部世界,尽管它确实缓解了fragile base class问题。

答案 1 :(得分:7)

在Objective C界面中,根本没有引用实例

设计Objective C的Brad Cox决定相应的C声明和定义应该是明确的,因此每个类都有一个@interface部分,告诉它外观是什么,以及@implementation说明它是如何实现的。

Java稍后出现并更改了对象模型,因此只有一个对象的定义将@interface和@implementation拉在一起。编译器(和运行时内省)实际上是从代码构造接口。

Java中的接口等效于Objective C中的协议。

你只是习惯了它。