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

发布于 2024-12-07 21:38:14 字数 361 浏览 0 评论 0原文

我想要一个可以通过导入头文件在任何地方访问的变量,但我也希望它是静态的,因为只创建了其中一个。在我的 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

GRAY°灰色天空 2024-12-14 21:38:14

在静态类数据成员和静态类方法的上下文中,Objective-C 中的static 与 C++ 类中的static 的含义不同。在 C 和 Objective-C 中,全局范围内的静态变量或函数意味着该符号具有内部链接。

内部链接意味着该符号是当前翻译单元的本地符号,即当前正在编译的源文件(.c.m)以及它递归包含的所有头文件。该符号不能从不同的翻译单元引用,并且您可以在具有相同名称的其他翻译单元中使用具有内部链接的其他符号。

因此,如果您有一个头文件将变量声明为static,则包含该头文件的每个源文件都会获得一个单独的全局变量 - 一个源文件中对该变量的所有引用将引用相同的变量,但不同源文件中的引用将引用不同的变量。

如果您想要单个全局变量,则不能像 C++ 那样将其放在类作用域中。一种选择是创建具有外部链接的全局变量:在头文件中使用 extern 关键字声明变量,然后在 one 源中声明该变量文件,在全局范围内定义它,而不使用 extern 关键字。内部链接和外部链接是互斥的——不能将变量同时声明为 externstatic

另一种方法是,正如 Panos 建议的,使用类方法而不是变量。这将功能保留在类的范围内,这在语义上更有意义,并且如果您愿意,也可以将其设置为 @private。它确实会增加边际性能损失,但这不太可能成为应用程序中的瓶颈(如果您怀疑它是,请始终首先进行分析)。

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.

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 the extern keyword. Internal linkage and external linkage are mutually exclusive—you cannot have a variable declared as both extern and static.

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).

深居我梦 2024-12-14 21:38:14

如果 LogStuff 是静态类字段,也许您可​​以实现静态 getter 和 setter?

+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;

If LogStuff is a static class field, maybe you can implement static getter and setter?

+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;
小女人ら 2024-12-14 21:38:14

在头文件中声明它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.

一梦等七年七年为一梦 2024-12-14 21:38:14

单独的全局变量(每个源文件一个):

// .h
static NSString * aStatic;

//.m
static NSString * aStatic = @"separate";

唯一的全局变量:

// .h
extern NSString * anExtern;

// .m
NSString * anExtern = @"global";

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";
伴我心暖 2024-12-14 21:38:14

我通常使用此布局进行静态分析:

NSMutableArray *macroArray;
BOOL keepMacro;

+ (void) startMacro
{
    if (macroArray == nil)
    {
        macroArray = [[NSMutableArray alloc] initWithCapacity:100];
    }

    [macroArray removeAllObjects];
    keepMacro = YES;
}

这是我的应用程序中的 startMacro 命令。 BoolmacroArray 都是静态的,但请注意它们没有声明为 staticextern

这可能不是最佳实践,但这就是我所做的。

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.

This may not be the best practice, but this is what I do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文