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
中声明?
答案 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
,所有这些引用都在同一个内存位置。