ios Objective-C 中的常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/538996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Constants in Objective-C
提问by Allyn
I'm developing a Cocoaapplication, and I'm using constant NSString
s as ways to store key names for my preferences.
我正在开发一个Cocoa应用程序,我使用常量NSString
s 作为存储我偏好的键名的方法。
I understand this is a good idea because it allows easy changing of keys if necessary.
Plus, it's the whole 'separate your data from your logic' notion.
我知道这是一个好主意,因为它允许在必要时轻松更改密钥。
另外,这是整个“将数据与逻辑分开”的概念。
Anyway, is there a good way to make these constants defined once for the whole application?
无论如何,有没有一种好方法可以为整个应用程序定义一次这些常量?
I'm sure that there's an easy and intelligent way, but right now my classes just redefine the ones they use.
我确信有一种简单而智能的方法,但现在我的类只是重新定义了它们使用的类。
回答by Barry Wark
You should create a header file like
您应该创建一个头文件,如
// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.
(you can use extern
instead of FOUNDATION_EXPORT
if your code will not be used in mixed C/C++ environments or on other platforms)
(如果您的代码不会在混合 C/C++ 环境或其他平台上使用extern
,FOUNDATION_EXPORT
则可以使用代替)
You can include this file in each file that uses the constants or in the pre-compiled header for the project.
您可以将此文件包含在每个使用常量的文件中或项目的预编译头文件中。
You define these constants in a .m file like
您在 .m 文件中定义这些常量,例如
// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";
Constants.m should be added to your application/framework's target so that it is linked in to the final product.
Constants.m 应该添加到您的应用程序/框架的目标中,以便将其链接到最终产品。
The advantage of using string constants instead of #define
'd constants is that you can test for equality using pointer comparison (stringInstance == MyFirstConstant
) which is much faster than string comparison ([stringInstance isEqualToString:MyFirstConstant]
) (and easier to read, IMO).
使用字符串常量而不是#define
'd 常量的优点是您可以使用指针比较 ( stringInstance == MyFirstConstant
)来测试相等性,这比字符串比较 ( [stringInstance isEqualToString:MyFirstConstant]
)快得多(并且更易于阅读,IMO)。
回答by Andrew Grant
Easiest way:
最简单的方法:
// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"
Better way:
更好的方法:
// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;
// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";
One benefit of the second is that changing the value of a constant does not cause a rebuild of your entire program.
第二种方法的一个好处是更改常量的值不会导致整个程序的重建。
回答by kompozer
There is also one thing to mention. If you need a non global constant, you should use static
keyword.
还有一件事要提。如果你需要一个非全局常量,你应该使用static
关键字。
Example
例子
// In your *.m file
static NSString * const kNSStringConst = @"const value";
Because of the static
keyword, this const is not visible outside of the file.
由于static
关键字,此常量在文件外部不可见。
Minor correction by @QuinnTaylor:static variables are visible within a compilation unit. Usually, this is a single .m file (as in this example), but it can bite you if you declare it in a header which is included elsewhere, since you'll get linker errors after compilation
@QuinnTaylor 的小修正:静态变量在编译单元中可见。通常,这是一个单独的 .m 文件(如本例中所示),但如果您在包含在其他地方的头文件中声明它,它会咬你,因为编译后会出现链接器错误
回答by Victor Van Hee
The accepted (and correct) answer says that "you can include this [Constants.h] file... in the pre-compiled header for the project."
已接受(且正确)的答案是“您可以将这个 [Constants.h] 文件...包含在项目的预编译头文件中。”
As a novice, I had difficulty doing this without further explanation -- here's how: In your YourAppNameHere-Prefix.pch file (this is the default name for the precompiled header in Xcode), import your Constants.h inside the #ifdef __OBJC__
block.
作为新手,我很难在没有进一步解释的情况下执行此操作 - 方法如下:在您的 YourAppNameHere-Prefix.pch 文件(这是 Xcode 中预编译头的默认名称)中,将您的 Constants.h 导入到#ifdef __OBJC__
block 中。
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "Constants.h"
#endif
Also note that the Constants.h and Constants.m files should contain absolutely nothing else in them except what is described in the accepted answer. (No interface or implementation).
另请注意,除了接受的答案中描述的内容外,Constants.h 和 Constants.m 文件中绝对不应包含任何其他内容。(没有接口或实现)。
回答by Krizz
I am generally using the way posted by Barry Wark and Rahul Gupta.
我通常使用 Barry Wark 和 Rahul Gupta 发布的方式。
Although, I do not like repeating the same words in both .h and .m file. Note, that in the following example the line is almost identical in both files:
虽然,我不喜欢在 .h 和 .m 文件中重复相同的词。请注意,在以下示例中,这两个文件中的行几乎相同:
// file.h
extern NSString* const MyConst;
//file.m
NSString* const MyConst = @"Lorem ipsum";
Therefore, what I like to do is to use some C preprocessor machinery. Let me explain through the example.
因此,我喜欢做的是使用一些 C 预处理器机器。让我通过例子来解释。
I have a header file which defines the macro STR_CONST(name, value)
:
我有一个定义宏的头文件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
The in my .h/.m pair where I want to define the constant I do the following:
在我要定义常量的 .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"
et voila, I have all the information about the constants in .h file only.
瞧,我只有 .h 文件中有关常量的所有信息。
回答by MaddTheSane
I myself have a header dedicated to declaring constant NSStrings used for preferences like so:
我自己有一个标题,专门用于声明用于首选项的常量 NSStrings,如下所示:
extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;
Then declaring them in the accompanying .m file:
然后在随附的 .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";
This approach has served me well.
这种方法对我很有帮助。
Edit: Note that this works best if the strings are used in multiple files. If only one file uses it, you can just do #define kNSStringConstant @"Constant NSString"
in the .m file that uses the string.
编辑:请注意,如果在多个文件中使用字符串,则此方法效果最佳。如果只有一个文件使用它,您可以#define kNSStringConstant @"Constant NSString"
在使用该字符串的 .m 文件中执行。
回答by Scott Little
A slight modification of the suggestion of @Krizz, so that it works properly if the constants header file is to be included in the PCH, which is rather normal. Since the original is imported into the PCH, it won't reload it into the .m
file and thus you get no symbols and the linker is unhappy.
对@Krizz 的建议稍作修改,以便在将常量头文件包含在 PCH 中时它可以正常工作,这是很正常的。由于原始文件已导入 PCH,因此它不会将其重新加载到.m
文件中,因此您不会得到任何符号并且链接器不满意。
However, the following modification allows it to work. It's a bit convoluted, but it works.
但是,以下修改允许它工作。这有点令人费解,但它有效。
You'll need 3files, .h
file which has the constant definitions, the .h
file and the .m
file, I'll use ConstantList.h
, Constants.h
and Constants.m
, respectively. the contents of Constants.h
are simply:
你需要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"
and the Constants.m
file looks like:
该Constants.m
文件如下所示:
// Constants.m
#ifdef STR_CONST
#undef STR_CONST
#endif
#define STR_CONST(name, value) NSString* const name = @ value
#include "ConstantList.h"
Finally, the ConstantList.h
file has the actual declarations in it and that is all:
最后,该ConstantList.h
文件中有实际的声明,仅此而已:
// ConstantList.h
STR_CONST(kMyConstant, "Value");
…
A couple of things to note:
有几点需要注意:
I had to redefine the macro in the
.m
file after#undef
ing it for the macro to be used.I also had to use
#include
instead of#import
for this to work properly and avoid the compiler seeing the previously precompiled values.This will require a recompile of your PCH (and probably the entire project) whenever any values are changed, which is not the case if they are separated (and duplicated) as normal.
我不得不重新定义宏
.m
文件后,#undef
荷兰国际集团它的宏观使用。我还必须使用
#include
而不是#import
为了使其正常工作并避免编译器看到以前预编译的值。这将需要在更改任何值时重新编译您的 PCH(可能还有整个项目),如果它们正常分离(和复制),则情况并非如此。
Hope that is helpful for someone.
希望这对某人有帮助。
回答by rahul gupta
// Prefs.h
extern NSString * const RAHUL;
// Prefs.m
NSString * const RAHUL = @"rahul";
回答by Grant Limberg
As Abizer said, you could put it into the PCH file. Another way that isn't so dirty is to make a include file for all of your keys and then either include that in the file you're using the keys in, or, include it in the PCH. With them in their own include file, that at least gives you one place to look for and define all of these constants.
正如Abizer所说,您可以将其放入PCH文件中。另一种不太脏的方法是为所有密钥创建一个包含文件,然后将其包含在您使用密钥的文件中,或者将其包含在 PCH 中。将它们放在自己的包含文件中,这至少为您提供了一个查找和定义所有这些常量的地方。
回答by Abizern
If you want something like global constants; a quick an dirty way is to put the constant declarations into the pch
file.
如果你想要全局常量之类的东西;一种快速而肮脏的方法是将常量声明放入pch
文件中。