2

如果你不考虑#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",但听起来有点奇怪。

4

2 回答 2

5

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

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

第二个问题更大——头文件包含常量的声明和定义。这意味着当您包含标头时,将再次创建常量。我认为从多个文件中包含这将无法正常工作。

第二个问题 - 长常量名没问题。您的示例有点极端,但没有任何问题。

编辑:添加有关static NSString* constin 标头的更多信息。让我们有一个标题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在头文件中使用,并且一切都会正常工作,但正如您所见,它并不能完全按照您的意愿进行,并且可能是难以发现的错误的来源。这就是为什么你应该static只使用来自实现文件的原因。

于 2012-12-04T10:13:39.590 回答
0

只是补充一下-您展示的第二种方式没有多大意义。

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

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

于 2012-12-04T10:24:44.433 回答