在@interface上面声明变量高于vs

时间:2012-03-16 05:39:18

标签: objective-c

int helloness;
@interface test : NSObject
@end

VS

 @interface test : NSObject{
int helloness;
}
@end

我是否理解以下是真实的以及上述两个块之间唯一有意义的差异:

  • 在两个块中,test.m的实现可以在内部使用helloness变量,如ivar
  • 在第一个块中,helloness将存在于导入此.h的任何类,但在第二个块中仅对test.m是私有的

在第一个区块中,这在技术上是什么被视为“全局变量”,因为任何导入它的类都可以访问helloness的相同内容?

如果多个头文件具有helloness声明并将其全部导入,会发生什么?

与此类似,请考虑以下实施:

 @implementation AClass

 int food=5;

在这里,food就像内部iVar一样,即使它没有在任何@interface中声明?

2 个答案:

答案 0 :(得分:2)

在您的第一个示例中,helloness是一个全局变量。在第二个例子中,它是一个实例变量。

程序中只能有一个具有给定名称的全局变量。在程序执行期间创建的每个类实例都有一个实例变量的副本。它们在语义上根本不相似。

在头文件中有一个全局变量,正如我在第一个例子中所做的那样,因为你引用它#import,这可能是一个坏主意。如果它不是像你那样的暂定定义(例如,如果你改为int helloness = 12;),那么你最终会在链接时出现多重定义的符号错误。

在上一个示例中,food仍然是一个全局变量,但由于它可能位于实现文件(而不是标题)中,因此您可能不会遇到任何多重定义的符号错误。它不会像实例变量一样工作 - 它仍然是一个全局变量。

答案 1 :(得分:2)

在您的第一个示例中,helloness是一个全局变量。任何导入该标头的文件都可以看到它。如果你包含多个也声明int helloness变量的标题,我相信你会收到编译器的警告,并且它们都会指向同一个内存位置。如果你包含另一个声明helloness类型而不是int的标题,我相信你会遇到编译错误。

在第二个示例中,helloness 一个实例变量(ivar)。其值(内存位置)特定于AClass的每个实例。 (任何东西都可以访问它:例如AClass *instance = [[AClass alloc] init]; instance->helloness = 7;但是,在ObjC中通常避免直接访问ivars - 我们使用访问器和/或属性。)

在第三种情况下,food仍然是一个全局变量,但其可见性仅限于它声明的实现文件。AClass的任何实例,以及任何其他类或类别或在同一个文件中实现的函数可以引用food,所有这些引用都在同一个内存位置。