关于在objective-c中声明常量

时间:2012-12-04 09:55:22

标签: objective-c

如果你不考虑#define,有两种臭名昭着的方法可以在objective-c项目中声明常量:

// Util.h
extern NSString * const MyConstant;

// Util.m
NSString * const MyConstant = @"value";

或其他直接在头文件中

// Util.h
static NSString *const MyConstant = @"value";

现在,有两个问题:

1) 两者都有效,第二种方法非常方便,因为我只有一个地方可以编辑值。 但是正如我从Apple .h文件中看到的那样,第一种方法总是首选,我想知道是否有任何缺点,使用静态方法。

2)看看Apple文档,我们经常遇到很长的常量名称,如: NSTextInputContextKeyboardSelectionDidChangeNotification 。在您使用类似长常量名称的情况下,您通常会使用什么约定来赋值。如果我想使用描述性的东西,我可以使用 @“nsTextInputContextKeyboardSelectionDidChangeNotification”,但听起来有些奇怪。

2 个答案:

答案 0 :(得分:5)

我不会向你解释两种类型的常量声明的所有细节 - 简而言之:

第一个将常量声明与常量定义分开。头文件仅包含声明。它还方便地隐藏了常数的实际值。

第二个问题更多 - 头文件包含常量的声明和定义。这意味着,如果包含标题,则会再次创建常量。从多个文件中包含时,我认为这不会正常工作。

第二个问题 - 长常数名称没问题。你的例子有点极端,但没有任何问题。

编辑:在标头中添加有关static NSString* const的更多信息。 我们有一个标题A.h

//A.h
static NSString *const MyConstant = @"value";

和包含它的文件A.m

//A.m
#import "A.h"

printA() {
   NSLog(@"A.h Constant: %@", MyConstant);
}

首先请注意,编译前预处理器会删除标头。这意味着在编译之前不会有任何A.h文件,A.m将如下所示:

//A.m
static NSString *const MyConstant = @"value";

printA() {
   NSLog(@"A.h Constant: %@", MyConstant);
}

让我们创建另一个常量标题B.h和实现文件B.m,内容完全相同:

//B.h
static NSString *const MyConstant = @"value2";
//B.m
#import "B.h"

printB() {
   NSLog(@"B.h Constant: %@", MyConstant);
}

请注意,常量声明两次,具有相同的名称和不同的值。这是可能的,因为static使包含它的文件的常量变为私有。如果删除static,则会出现编译错误,因为编译器会找到两个具有相同名称的公共全局常量。

从理论上讲,可以在头文件中使用static NSString* const,一切都能正常工作,但正如您所看到的,它并不能完全符合您的要求,并且可能成为难以发现的bug的来源。这就是为什么你应该只从实现文件中使用static

答案 1 :(得分:0)

只是添加 - 你所展示的第二种方式没有多大意义。

如果要在一个地方声明和定义常量,例如,通常在.m文件而不是.h文件中完成。

对于只会在类本身中使用但未公开的常量,您可以这样做。