【问题标题】:Objective-C static, extern, public variablesObjective-C 静态、外部、公共变量
【发布时间】:2011-11-30 08:02:38
【问题描述】:

我希望有一个变量,我可以通过导入头文件在任何地方访问它,但我也希望它是静态的,因为只创建了一个。在我的 .m 文件中,我指定了

static BOOL LogStuff = NO;

在初始化方法中我设置了日志记录值:

+ (void)initialize
{
    LogStuff = ... //whatever
}

但是我希望能够通过导入 .h 文件在任何地方访问我的变量,所以我想做这样的事情:

static extern BOOL LogStuff;

但我不允许这样做。有可能做我想做的事情吗?谢谢

【问题讨论】:

    标签: objective-c static public extern


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      在你的头文件中声明它extern BOOL#import 您的标头不知道或不关心外部符号是否为静态的文件。

      【讨论】:

        【解决方案3】:

        我通常将这种布局用于我的静态:

        NSMutableArray *macroArray;
        BOOL keepMacro;
        
        + (void) startMacro
        {
            if (macroArray == nil)
            {
                macroArray = [[NSMutableArray alloc] initWithCapacity:100];
            }
        
            [macroArray removeAllObjects];
            keepMacro = YES;
        }
        

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

        这可能不是最佳做法,但我就是这样做的。

        【讨论】:

          【解决方案4】:

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

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

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

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

          作为Panos suggested 的替代方法是使用类方法而不是变量。这将功能保持在类的范围内,这在语义上更有意义,如果您愿意,也可以将其设为 @private。它确实增加了边际性能损失,但这不太可能成为您的应用程序的瓶颈(如果您怀疑是,请始终先配置文件)。

          【讨论】:

          • "然后在一个源文件中,在全局范围内定义它而不使用 extern 关键字" => 如果我不这样做会怎样?我很惊讶没有编译器错误。
          • @huggie:您很可能会收到链接器错误,例如“未找到符号”或“重复符号”。
          • +1 表示“内部链接和外部链接互斥”
          • "在一个源文件中对该变量的所有引用都将引用同一个变量,但不同源文件中的引用将引用不同的变量。"我创建了一个项目来尝试重新创建它,但我遇到了麻烦。我创建了一个声明静态变量的标头 (StaticHeader01.h),以及导入 StaticHeader01.h 并打印出静态变量的内存地址的另外两个文件 (Test01.h|m Test02.h|m)。但是,内存地址是相同的。你能指出我错过了什么吗?
          • @AdamRosenfield: 声明一个全局的 const NSString 有和没有 static 关键字有什么区别吗?如果它是全局的,关键字 static 是否添加任何值?静态 NSString *const kSiteURL = @“google.com”; vs NSString *const kSiteURL = @“google.com”;
          【解决方案5】:

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

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

          唯一的全局变量:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-09-23
            • 1970-01-01
            • 2012-07-14
            • 2011-08-27
            • 2017-06-30
            • 2013-04-01
            相关资源
            最近更新 更多