我想有一个变量,我可以通过导入头文件访问任何地方,但我也希望它是静态的,因为只有其中一个被创建。在我的。m文件中,我指定
static BOOL LogStuff = NO;
在initialize方法中,我设置了日志记录值:
+ (void)initialize
{
LogStuff = ... //whatever
}
然而,我希望能够通过导入。h文件来访问我的变量,所以我想这样做:
static extern BOOL LogStuff;
但是我不允许那样做。我想做的事有可能做到吗?由于
static
在Objective-C中的含义与static
在c++类中的含义不同。在C和Objective-C中,全局作用域的static
变量或函数意味着该符号具有内部链接。
内部链接意味着该符号对于当前翻译单元是本地的,该单元是正在编译的当前源文件(.c
或.m
)以及它递归包含的所有头文件。该符号不能从不同的翻译单元引用,并且您可以在其他翻译单元中使用具有相同名称的内部链接的其他符号。
所以,如果你有一个头文件声明一个变量为static
,每个包含该头文件的源文件将获得一个独立的全局变量——在一个源文件中对该变量的所有引用将引用同一个变量,但在不同的源文件中引用将引用不同的变量。
如果你想有一个单一的全局变量,你不能像在c++中那样把它放在类的作用域中。一种选择是创建一个具有外部链接的全局变量:在头文件中使用extern
关键字声明该变量,然后在一个源文件中,在全局范围内定义它,而不使用extern
关键字。内部链接和外部链接是互斥的——一个变量不能同时声明为extern
和static
。
正如Panos建议的那样,另一种方法是使用类方法而不是变量。这使功能保持在类的范围内,这在语义上更有意义,如果您愿意,还可以将其设置为@private
。它确实增加了边际性能损失,但这极不可能成为应用程序的瓶颈(如果您怀疑是瓶颈,请始终首先配置文件)。
如果LogStuff
是一个静态类字段,也许你可以实现静态getter和setter?
+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;
在头文件中声明为extern BOOL
。#import
头文件不知道或关心外部符号是否是静态的
单独的全局变量(每个源文件一个):
// .h
static NSString * aStatic;
//.m
static NSString * aStatic = @"separate";
唯一全局变量:
// .h
extern NSString * anExtern;
// .m
NSString * anExtern = @"global";
我通常使用这种布局的静态:
NSMutableArray *macroArray;
BOOL keepMacro;
+ (void) startMacro
{
if (macroArray == nil)
{
macroArray = [[NSMutableArray alloc] initWithCapacity:100];
}
[macroArray removeAllObjects];
keepMacro = YES;
}
这是我应用程序中的startMacro
命令。Bool
和macroArray
都是静态的,但请注意它们没有声明为static
或extern
。
这可能不是最好的做法,但我就是这么做的。