Objective-C静态,外部,公共变量

时间:2022-09-07 19:34:02

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.

这也许不是最好的做法,但我就是这么做的。