Objective-C 静态、外部、公共变量
我想要一个可以通过导入头文件在任何地方访问的变量,但我也希望它是静态的,因为只创建了其中一个。在我的 .m 文件中,我指定
static BOOL LogStuff = NO;
并在初始化方法中设置日志记录值:
+ (void)initialize
{
LogStuff = ... //whatever
}
但是我希望能够通过导入 .h 文件在任何地方访问我的变量,所以我想做这样的事情:
static extern BOOL LogStuff;
但我不是允许这样做。我想做的事情有可能吗?谢谢
I want to have a variable that I can access anywhere by importing a header file but I also want it to be static in the sense that there is only one of them created. In my .m file, I specify
static BOOL LogStuff = NO;
and in the initialize method I set the logging value:
+ (void)initialize
{
LogStuff = ... //whatever
}
However I want to be able to access my variable anywhere by importing the .h file so I want to do something like this:
static extern BOOL LogStuff;
but I'm not allowed to do that. Is it possible to do the thing I'm trying to do? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在静态类数据成员和静态类方法的上下文中,Objective-C 中的
static
与 C++ 类中的static
的含义不同。在 C 和 Objective-C 中,全局范围内的静态变量或函数意味着该符号具有内部链接。内部链接意味着该符号是当前翻译单元的本地符号,即当前正在编译的源文件(
.c
或.m
)以及它递归包含的所有头文件。该符号不能从不同的翻译单元引用,并且您可以在具有相同名称的其他翻译单元中使用具有内部链接的其他符号。因此,如果您有一个头文件将变量声明为
static
,则包含该头文件的每个源文件都会获得一个单独的全局变量 - 一个源文件中对该变量的所有引用将引用相同的变量,但不同源文件中的引用将引用不同的变量。如果您想要单个全局变量,则不能像 C++ 那样将其放在类作用域中。一种选择是创建具有外部链接的全局变量:在头文件中使用
extern
关键字声明变量,然后在 one 源中声明该变量文件,在全局范围内定义它,而不使用extern
关键字。内部链接和外部链接是互斥的——不能将变量同时声明为extern
和static
。另一种方法是,正如 Panos 建议的,使用类方法而不是变量。这将功能保留在类的范围内,这在语义上更有意义,并且如果您愿意,也可以将其设置为
@private
。它确实会增加边际性能损失,但这不太可能成为应用程序中的瓶颈(如果您怀疑它是,请始终首先进行分析)。static
in Objective-C means a different thing thanstatic
in a C++ class, in the context of static class data members and static class methods. In C and Objective-C, astatic
variable or function at global scope means that that symbol has internal linkage.Internal linkage means that that symbol is local to the current translation unit, which is the current source file (
.c
or.m
) being compiled and all of the header files that it recursively includes. That symbol cannot be referenced from a different translation unit, and you can have other symbols with internal linkage in other translation units with the same name.So, if you have a header file declaring a variable as
static
, each source file that includes that header gets a separate global variable—all references to that variable within one source file will refer to the same variable, but references in different source files will refer to different variables.If you want to have a single global variable, you can't have it in class scope like in C++. One option is to create a global variable with external linkage: declare the variable with the
extern
keyword in a header file, and then in one source file, define it at global scope without theextern
keyword. Internal linkage and external linkage are mutually exclusive—you cannot have a variable declared as bothextern
andstatic
.An alternative, as Panos suggested, would be to use a class method instead of a variable. This keeps the functionality within the scope of the class, which makes more sense semantically, and you can also make it
@private
if you so desire. It does add a marginal performance penalty, but that's highly unlikely to be the bottleneck in your application (if you suspect it is, always profile first).如果 LogStuff 是静态类字段,也许您可以实现静态 getter 和 setter?
If
LogStuff
is a static class field, maybe you can implement static getter and setter?在头文件中声明它
extern BOOL
。#import
标头的文件不知道或关心外部符号是否静态。Declare it
extern BOOL
in your header file. Files that#import
your header don't know or care if the external symbol is static or not.单独的全局变量(每个源文件一个):
唯一的全局变量:
Separate global variable (one per source file):
Unique global variable:
我通常使用此布局进行静态分析:
这是我的应用程序中的
startMacro
命令。Bool
和macroArray
都是静态的,但请注意它们没有声明为static
或extern
。这可能不是最佳实践,但这就是我所做的。
I normally use this layout for my statics:
This is the
startMacro
command in my application. Both theBool
and themacroArray
are static, but notice they are not declaredstatic
orextern
.This may not be the best practice, but this is what I do.