静态const与extern const有何不同?

时间:2014-12-11 00:08:30

标签: ios objective-c

在我的iOS / Objective C项目中,我经常使用带有API密钥等的constants.h文件。直到今天,我一直宣称我的常量为static const,如此:

static NSString * const kAPIKey = @"wembvkejrvb43789gvbiu2bvfake";

这很好用,但有一个不幸的缺点,我可以创建基元和NSString文字的常量。其他对象(如UIColor对象)不能存储在此常量中,因为它们无法使用静态文字语法进行初始化(我的理解,需要引用)。

在阅读了一些C ++文档后,我理解了一些事情:

  • static是不必要的,因为const是隐式静态的。
  • 调用NSString * const x实际上是在x中声明一个常量且不可变的值。我无法更改值,但可以更改x指向的内容。
  • 此const具有内部链接,意味着该值立即定义(在编译时可以推测)。

这些结论是否正确?

extern const有何不同?我假设它们是外部链接的(因此是extern关键字)。它们是在运行时定义的吗?我可以创建某种动态 extern const,可以使用类方法返回的值进行设置吗?

例如,我想创建一个包含UIColor值的全局范围常量。我想使用[UIColor colorWithRed:green:blue:alpha:]类方法构造此颜色值。这显然不适用于我一直在使用的内部链接常量(我假设因为它发生在编译时) - 但可能使用外部常量,可能在+initialize方法中设置?

任何有关此行为细节的详细说明都会非常有用。

3 个答案:

答案 0 :(得分:8)

  

静态是不必要的,因为const是隐式静态的。

不,那不是真的。

static在文件范围内使用时(即在任何方法或函数之外)意味着该变量仅在该文件中可见。

extern表示该变量在其他文件中定义。

const表示无法修改变量。

考虑字符串。通常,您将有一个实现文件(名称以.m结尾)定义一些常量字符串指针:

NSString *const SomeString = @"some string";

您可能希望从其他文件中使用相同的常量。如果是这样,你可以在标题中添加一个声明(名称以.h结尾)文件,向编译器解释变量是在别处定义的:

extern NSString *const SomeString;

这将允许您在导入头文件的任何文件中使用SomeString。另一方面,您可能会认为您确实希望在实现文件外部使用常量。在这种情况下,您可以声明它static(再次在实现文件中):

static NSString *const SomeString = @"some string";

这会阻止它在文件外使用。

  

调用NSString * const x实际上是在x中声明一个常量且不可变的值。我无法更改值,但可以更改x指向的内容。

是的,它声明指针x是常量 - 你无法改变它。如果它实际上是NSString,您也无法更改其指向的值,因为实例NSString不可变。

  

此const具有内部链接,意味着该值立即定义(在编译时可以推测)。

我将在第5位 - 我不确定编译器如何处理常量字符串。不过,我认为将其用作心理模型是安全的。在任何情况下,字符串都会在您的代码使用之前定义。

答案 1 :(得分:1)

关于您的特定编程问题,如何创建编译时定义的颜色对象:您不能,因为除了少数语言提供文字语法之外,还会在运行时创建对象。

但是你仍然可以在运行时优雅地完成它,而不会增加全局范围,就像sdk所做的那样......

@interface UIColor (RainbowAddition)

+ (UIColor *)chartruseColor;

@end

@implementation UIColor (RainbowAddition)

+ (UIColor *)chartruseColor {
    // bonus: this is really chartruse... according to the internet
    return [self colorWithRed:0.5 green:1.0 blue:0.0 alpha:1.0];
}

@end

http://cloford.com/resources/colours/500col.htm

答案 2 :(得分:1)

Objective-C是C的纯粹扩展,C ++不是。

在全球范围内:

  • 在C(和Objective-C)中写const相当于extern const(外部链接);
  • 在C ++中编写const等同于static const(内部链接)。

在C(和Objective-C)和C ++中,要创建一个全局范围的const,您只需在extern const TYPE identifier = VALUE;之类的源文件中定义它,并声明它(通常在头文件中):extern const TYPE identifier;(读它:我在全局链接级别的其他地方定义了这个const)。