我正在开发一个Cocoa应用程序,我使用常量nsstring作为存储我的首选项的键名的方式。

我知道这是一个好主意,因为它允许在必要时轻松更改密钥。 此外,这是整个“将数据与逻辑分离”的概念。

不管怎样,有没有一种好方法让这些常量在整个应用程序中定义一次?

我相信有一种简单而聪明的方法,但现在我的类只是重新定义它们所使用的方法。


当前回答

如果你喜欢命名空间常量,你可以使用struct,周五问答2011-08-19:命名空间常量和函数

// in the header
extern const struct MANotifyingArrayNotificationsStruct
{
    NSString *didAddObject;
    NSString *didChangeObject;
    NSString *didRemoveObject;
} MANotifyingArrayNotifications;

// in the implementation
const struct MANotifyingArrayNotificationsStruct MANotifyingArrayNotifications = {
    .didAddObject = @"didAddObject",
    .didChangeObject = @"didChangeObject",
    .didRemoveObject = @"didRemoveObject"
};

其他回答

如果你想要全局常数;一种快速但肮脏的方法是将常量声明放入PCH文件中。

简单的方法:

// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"

更好的办法:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

第二种方法的一个好处是,改变常量的值不会导致整个程序的重新构建。

对@Krizz的建议进行了轻微修改,以便在常量头文件被包含在PCH中时正常工作,这是相当正常的。由于原始文件被导入到PCH中,它不会重新加载到.m文件中,因此您没有得到任何符号,链接器也不高兴。

但是,下面的修改允许它工作。这有点复杂,但很有效。

你需要3个文件,。h文件有常量定义,.h文件和。m文件,我将使用ConstantList.h, Constants.h和Constants。m,分别。Constants.h的内容很简单:

// Constants.h
#define STR_CONST(name, value) extern NSString* const name
#include "ConstantList.h"

和常数。M文件如下所示:

// Constants.m
#ifdef STR_CONST
    #undef STR_CONST
#endif
#define STR_CONST(name, value) NSString* const name = @ value
#include "ConstantList.h"

最后,ConstantList.h文件中有实际的声明,这就是全部:

// ConstantList.h
STR_CONST(kMyConstant, "Value");
…

有几点需要注意:

我必须在.m文件中#undefing后重新定义宏。 我还必须使用#include而不是#import来正常工作,并避免编译器看到之前预编译的值。 这将需要在任何值发生更改时重新编译PCH(可能还包括整个项目),如果正常情况下将它们分开(并复制),则不会出现这种情况。

希望这对大家有所帮助。

正如Abizer所说,您可以将其放入PCH文件中。另一种不那么脏的方法是为所有键创建一个包含文件,然后将其包含在您使用键的文件中,或者将其包含在PCH中。在它们自己的包含文件中,至少给了您一个查找和定义所有这些常量的地方。

如果你喜欢命名空间常量,你可以使用struct,周五问答2011-08-19:命名空间常量和函数

// in the header
extern const struct MANotifyingArrayNotificationsStruct
{
    NSString *didAddObject;
    NSString *didChangeObject;
    NSString *didRemoveObject;
} MANotifyingArrayNotifications;

// in the implementation
const struct MANotifyingArrayNotificationsStruct MANotifyingArrayNotifications = {
    .didAddObject = @"didAddObject",
    .didChangeObject = @"didChangeObject",
    .didRemoveObject = @"didRemoveObject"
};