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
我希望有一个可以通过导入头文件访问的变量,但我也希望它是静态的,因为只创建了其中的一个。在我的.m文件中,我指定
static BOOL LogStuff = NO;
and in the initialize method I set the logging value:
在initialize方法中,我设置日志值:
+ (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:
但是我想通过导入。h文件来访问我的变量所以我想这样做:
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
但我不能这么做。有可能做我想做的事吗?谢谢
5 个解决方案
#1
121
static
in Objective-C means a different thing than static
in a C++ class, in the context of static class data members and static class methods. In C and Objective-C, a static
variable or function at global scope means that that symbol has internal linkage.
Objective-C中的static表示与c++类中的static(静态类数据成员和静态类方法)不同。在C和Objective-C中,全局作用域中的静态变量或函数意味着符号具有内部链接。
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.
内部链接意味着该符号是当前翻译单元(即当前源文件)的本地符号。c或.m)正在编译和它递归包含的所有头文件。该符号不能从不同的翻译单元引用,您可以在其他名称相同的翻译单元中使用具有内部链接的其他符号。
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 the extern
keyword. Internal linkage and external linkage are mutually exclusive—you cannot have a variable declared as both extern
and static
.
如果想要一个全局变量,就不能像c++那样在类作用域中使用它。一种选择是创建一个带有外部链接的全局变量:在头文件中声明带有extern关键字的变量,然后在一个源文件中,在全局范围中定义它而不使用extern关键字。内部链接和外部链接是相互排斥的——您不能有一个声明为外部和静态的变量。
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).
正如Panos所建议的,另一种选择是使用类方法而不是变量。这将使功能保持在类的范围内,这在语义上更有意义,如果您愿意,也可以将其设置为@private。它确实增加了边际性能损失,但这几乎不可能成为应用程序中的瓶颈(如果您怀疑这一点,请始终先进行概要分析)。
#2
4
If LogStuff
is a static class field, maybe you can implement static getter and setter?
如果LogStuff是一个静态类字段,那么可以实现静态getter和setter吗?
+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;
#3
3
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.
在头文件中声明它extern BOOL。#导入头的文件不知道或不关心外部符号是否是静态的。
#4
1
Separate global variable (one per source file):
单独的全局变量(每个源文件一个):
// .h
static NSString * aStatic;
//.m
static NSString * aStatic = @"separate";
Unique global variable:
独特的全局变量:
// .h
extern NSString * anExtern;
// .m
NSString * anExtern = @"global";
#5
0
I normally use this layout for my statics:
我通常使用这个布局为我的静态:
NSMutableArray *macroArray;
BOOL keepMacro;
+ (void) startMacro
{
if (macroArray == nil)
{
macroArray = [[NSMutableArray alloc] initWithCapacity:100];
}
[macroArray removeAllObjects];
keepMacro = YES;
}
This is the startMacro
command in my application. Both the Bool
and the macroArray
are static, but notice they are not declared static
or extern
.
这是我的应用程序中的startMacro命令。Bool和宏数组都是静态的,但是请注意,它们不是声明为静态的或extern。
This may not be the best practice, but this is what I do.
这也许不是最好的做法,但我就是这么做的。
#1
121
static
in Objective-C means a different thing than static
in a C++ class, in the context of static class data members and static class methods. In C and Objective-C, a static
variable or function at global scope means that that symbol has internal linkage.
Objective-C中的static表示与c++类中的static(静态类数据成员和静态类方法)不同。在C和Objective-C中,全局作用域中的静态变量或函数意味着符号具有内部链接。
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.
内部链接意味着该符号是当前翻译单元(即当前源文件)的本地符号。c或.m)正在编译和它递归包含的所有头文件。该符号不能从不同的翻译单元引用,您可以在其他名称相同的翻译单元中使用具有内部链接的其他符号。
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 the extern
keyword. Internal linkage and external linkage are mutually exclusive—you cannot have a variable declared as both extern
and static
.
如果想要一个全局变量,就不能像c++那样在类作用域中使用它。一种选择是创建一个带有外部链接的全局变量:在头文件中声明带有extern关键字的变量,然后在一个源文件中,在全局范围中定义它而不使用extern关键字。内部链接和外部链接是相互排斥的——您不能有一个声明为外部和静态的变量。
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).
正如Panos所建议的,另一种选择是使用类方法而不是变量。这将使功能保持在类的范围内,这在语义上更有意义,如果您愿意,也可以将其设置为@private。它确实增加了边际性能损失,但这几乎不可能成为应用程序中的瓶颈(如果您怀疑这一点,请始终先进行概要分析)。
#2
4
If LogStuff
is a static class field, maybe you can implement static getter and setter?
如果LogStuff是一个静态类字段,那么可以实现静态getter和setter吗?
+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;
#3
3
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.
在头文件中声明它extern BOOL。#导入头的文件不知道或不关心外部符号是否是静态的。
#4
1
Separate global variable (one per source file):
单独的全局变量(每个源文件一个):
// .h
static NSString * aStatic;
//.m
static NSString * aStatic = @"separate";
Unique global variable:
独特的全局变量:
// .h
extern NSString * anExtern;
// .m
NSString * anExtern = @"global";
#5
0
I normally use this layout for my statics:
我通常使用这个布局为我的静态:
NSMutableArray *macroArray;
BOOL keepMacro;
+ (void) startMacro
{
if (macroArray == nil)
{
macroArray = [[NSMutableArray alloc] initWithCapacity:100];
}
[macroArray removeAllObjects];
keepMacro = YES;
}
This is the startMacro
command in my application. Both the Bool
and the macroArray
are static, but notice they are not declared static
or extern
.
这是我的应用程序中的startMacro命令。Bool和宏数组都是静态的,但是请注意,它们不是声明为静态的或extern。
This may not be the best practice, but this is what I do.
这也许不是最好的做法,但我就是这么做的。