如果你不考虑#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”,但听起来有些奇怪。
答案 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文件中完成。
对于只会在类本身中使用但未公开的常量,您可以这样做。