cocoa - ObjectiveC 中的常量

  显示原文与译文双语对照的内容

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

我明白这是个好主意,因为它允许在必要的时候改变按键。 另外,这是整个'将数据与逻辑分离'的概念。

无论如何,是否有一个好方法来为整个应用程序定义这些常量一次? 我确信有一种简单而智能的方法,但是现在我的类只是重新定义它们使用的那些。

时间:

你应该创建一个头文件,比如


//Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.

(你可以用 extern 代替 FOUNDATION_EXPORT 如果你的代码将不会使用混合 C/C++ 环境中或在其他平台上)

可以将这里文件包含在每个使用常量的文件中,也可以包含在项目的pre-compiled标头中。

在. m 文件中定义这些常数,比如


//Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";

Constants.m 应该添加到应用程序/框架的目标,以便它链接到最终产品。

使用字符串常量而不是 #define的优点是,你可以使用指针比较( stringInstance == MyFirstConstant ) 测试相等性,它比字符串比较( [stringInstance isEqualToString:MyFirstConstant] ) ( 更容易阅读,IMO ) 。

最简单的方法:


//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";

第二个好处是更改常量的值不会导致整个程序的重建。

还有一件事需要提及。 如果你需要一个非全局常量,你应该使用 static 关键字。

例子


//In your *.m file
static NSString * const kNSStringConst = @"const value";

由于 static 关键字,这里常量在文件之外不可见。


小校正由 @QuinnTaylor : 静态变量在 。编译单元中可见。 通常,这是一个( 在本例中). m 文件,但是它能咬你如果你声明一个头包括在其他地方,因为编译后你将得到链接错误

接受的( 并更正) 回答表示"你可以包含这里 [Constants.h] 文件。"。 在pre-compiled标题为项目中。"作为一个新手做这个,我有难度并未给出进一步的说明--具体方法如下: 在 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 文件中常量的所有信息。

对 @Krizz,的建议稍作修改,以便在将常量头文件包含在PCH中时可以正常工作,这相当普通。 由于原始文件被导入到PCH中,它不会将它重新加载到 .m 文件中,因此你没有任何符号和链接器不高兴。

但是,下面的修改允许它工作。 有点复杂,但是它可以。

你需要 3 文件, .h 文件常数定义, .h 文件和 .m 文件,我将使用 ConstantList.hConstants.hConstants.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");
…

要注意以下几个事项:

  1. 我不得不重新定义 .m 文件中的宏#undef ing宏的使用它。

  2. 我也必须使用 #include 相反的#import 正常工作,避免编译器看到前面预编译的值。

  3. 这需要在任何值更改时重新编译 PCH ( 可能整个项目),如果它们是正常的,则不区分大小写。

希望对某人有帮助。

我自己拥有一个用于声明常量NSStrings的标题,比如:


extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;

然后在附带的. m file: 中声明它们


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";

这种方法为我提供了良好的服务。

编辑:注意,如果字符串在多个文件中使用,这将是最好的。 如果只有一个文件使用它,你就可以 #define kNSStringConstant @"Constant NSString" 在使用字符串的. m 文件中。

...