NSString
作为存储首选项键名的方法。我知道这是一个好主意,因为它允许在必要时轻松更改键。
此外,这是“将数据与逻辑分离”的整体概念。
无论如何,有没有一种好的方法可以使这些常量为整个应用程序定义一次?
我相信有一种简单而聪明的方法,但现在我的类只是重新定义它们使用的那些常量。
你应该创建一个像这样的头文件:
// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.
如果你的代码不会在混合C / C ++环境或其他平台上使用,可以使用extern
代替FOUNDATION_EXPORT
。
您可以将此文件包含在每个使用常量的文件中,也可以将其包含在项目的预编译标头中。
您可以在.m
文件中定义这些常量,例如:
// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";
需要将Constants.m
添加到您的应用程序/框架的目标中,以便它链接到最终产品中。
使用字符串常量而不是#define
常量的优点是可以使用指针比较(stringInstance == MyFirstConstant
)进行相等性测试,这比字符串比较([stringInstance isEqualToString:MyFirstConstant]
)更快(在我看来更易读)。
NSString
属性定义为 copy
而不是 retain
。因此,它们可以(也应该)保存一个不同的实例,而直接内存地址比较将失败。另外,我认为任何合理优化的 -isEqualToString:
实现都会在进行字符比较之前检查指针相等性。 - Ben Mosher最简单的方法:
// 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";
第二种方法的一个好处是,更改常量的值并不会导致整个程序重新构建。
extern NSString const * const MyConstant
时,即将其设置为常量指针指向常量对象,相比于仅将其设置为常量指针,是否有任何附加价值? - Hari Honorstatic
关键字。// In your *.m file
static NSString * const kNSStringConst = @"const value";
static
关键字,这个常量在文件外不可见。
@QuinnTaylor 进行了小的修正: 静态变量在编译单元内是可见的。通常,这是一个单独的 .m 文件(就像这个例子中一样),但如果你在其他地方包含了一个头文件并在其中声明了它,那么它可能会让你遇到链接器错误。
STRING_CONST
而不是StringConst
?这只存在于Java世界中吗? - Iulian Onofrei接受(且正确)的答案说“你可以在项目的预编译头文件中包含这个[Constants.h]文件……”
作为一个新手,我很难在没有进一步的解释下做到这一点——以下是方法:在您的YourAppNameHere-Prefix.pch文件中(这是Xcode中预编译头文件的默认名称),将Constants.h导入 #ifdef __OBJC__
块内。
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "Constants.h"
#endif
还要注意的是,Constants.h和Constants.m文件中除了已接受答案中描述的内容之外,绝不能包含其他任何内容。(不包括接口或实现部分)。
我通常使用Barry Wark和Rahul Gupta发布的方式。
虽然我不喜欢在.h和.m文件中重复相同的单词。 注意,在下面的示例中,这一行在两个文件中几乎完全相同:
// file.h
extern NSString* const MyConst;
//file.m
NSString* const MyConst = @"Lorem ipsum";
因此,我想要做的是使用一些C预处理器机制。让我通过一个例子来解释一下。STR_CONST(name, value)
:// StringConsts.h
#ifdef SYNTHESIZE_CONSTS
# define STR_CONST(name, value) NSString* const name = @ value
#else
# define STR_CONST(name, value) extern NSString* const name
#endif
在我的.h/.m文件对中常量进行定义,我按照以下方式操作:
// myfile.h
#import <StringConsts.h>
STR_CONST(MyConst, "Lorem Ipsum");
STR_CONST(MyOtherConst, "Hello world");
// myfile.m
#define SYNTHESIZE_CONSTS
#import "myfile.h"
然后,我只需要查看.h文件中所有常量的信息即可。
我自己有一个头文件,专门用于声明常量NSString,用于类似偏好设置的用途,就像这样:
extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;
然后在相应的.m文件中声明它们:
NSString * const PPRememberMusicList = @"Remember Music List";
NSString * const PPLoadMusicAtListLoad = @"Load music when loading list";
NSString * const PPAfterPlayingMusic = @"After playing music";
NSString * const PPGotoStartupAfterPlaying = @"Go to startup pos. after playing";
这种方法对我非常有帮助。
编辑:请注意,如果字符串在多个文件中使用,则此方法效果最佳。如果只有一个文件使用它,则可以在使用该字符串的 .m 文件中执行 #define kNSStringConstant @"Constant NSString"
。
以下是对@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"
而Constants.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
文件中重新定义宏,在使用#undef
取消定义之后才能使用该宏。
我还必须使用#include
而不是#import
,以使其正常工作并避免编译器看到先前预编译的值。
每当更改任何值时,这将需要重新编译您的PCH(可能是整个项目),如果它们被分开(并且重复)存储,则情况就不同。
希望对某些人有所帮助。
FOUNDATION_EXPORT
替换上面的extern
,它们将完全相同。 - Scott Little// Prefs.h
extern NSString * const RAHUL;
// Prefs.m
NSString * const RAHUL = @"rahul";
正如Abizer所说,你可以将它放入PCH文件中。另一种不那么粗糙的方法是为所有密钥创建一个包含文件,然后将其包含在使用密钥的文件中,或将其包含在PCH中。将它们放在自己的包含文件中,至少可以让你在一个地方查找和定义所有这些常量。
如果您需要像全局常量一样的东西;一个快速而简单的方法是将常量声明放入 pch
文件中。