Objective-C 中的常量
我正在开发一个 Cocoa 应用程序,并且我正在使用常量 NSString 是根据我的喜好存储键名的方法。
我知道这是一个好主意,因为它可以在必要时轻松更改密钥。
另外,这就是“将数据与逻辑分开”的整个概念。
无论如何,有没有一个好的方法可以让这些常量为整个应用程序定义一次?
我确信有一种简单而智能的方法,但现在我的课程只是重新定义了他们使用的方法。
I'm developing a Cocoa application, and I'm using constant NSString
s as ways to store key names for my preferences.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
应该创建一个像这样的头文件:(
如果您的代码不会在混合 C/C++ 环境或其他平台上使用,则可以使用
extern
而不是FOUNDATION_EXPORT
。)您 可以将此文件包含在使用常量的每个文件中或项目的预编译头中。
您可以在
.m
文件中定义这些常量,例如:Constants.m
应添加到您的应用程序/框架的目标中,以便将其链接到最终产品。使用字符串常量而不是 #define 的常量的优点是,您可以使用指针比较 (
stringInstance == MyFirstConstant
) 来测试相等性,这比字符串比较快得多([stringInstance isEqualToString:MyFirstConstant]
) (并且更易于阅读,IMO)。You should create a header file like:
(You can use
extern
instead ofFOUNDATION_EXPORT
if your code will not be used in mixed C/C++ environments or on other platforms.)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:Constants.m
should be added to your application/framework's target so that it is linked in to the final product.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).最简单的方法:
更好的方法:
第二种方法的好处之一是更改常量的值不会导致整个程序的重建。
Easiest way:
Better way:
One benefit of the second is that changing the value of a constant does not cause a rebuild of your entire program.
还有一点值得一提。 如果你需要一个非全局常量,你应该使用
static
关键字。示例
由于
static
关键字,此常量在文件外部不可见。由@QuinnTaylor进行的小修正:静态变量在编译单元中可见 。 通常,这是一个单个 .m 文件(如本例所示),但如果您在其他地方包含的标头中声明它,它可能会困扰您,因为编译后您将收到链接器错误
There is also one thing to mention. If you need a non global constant, you should use
static
keyword.Example
Because of the
static
keyword, this const is not visible outside of the file.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
接受的(正确的)答案是“您可以包含这个 [Constants.h] 文件......在项目的预编译头中。”
作为一个新手,如果没有进一步的解释,我很难做到这一点 - 方法如下:在 YourAppNameHere-Prefix.pch 文件(这是 Xcode 中预编译标头的默认名称)中,将 Constants.h 导入到 <代码>#ifdef __OBJC__ 块。
另请注意,除了接受的答案中描述的内容之外,Constants.h 和 Constants.m 文件中绝对不应包含任何其他内容。 (没有接口或实现)。
The accepted (and correct) answer says that "you can include this [Constants.h] file... in the pre-compiled header for the project."
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.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).
我通常使用 Barry Wark 和 Rahul Gupta 发布的方式。
虽然,我不喜欢在 .h 和 .m 文件中重复相同的单词。
请注意,在下面的示例中,两个文件中的行几乎相同:
因此,我喜欢做的是使用一些 C 预处理器机制。
让我通过例子来解释一下。
我有一个定义宏
STR_CONST(name, value)
的头文件:在我的 .h/.m 对中,我想定义常量,我执行以下操作:
等瞧,我拥有所有仅有关 .h 文件中常量的信息。
I am generally using the way posted by Barry Wark and 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:
Therefore, what I like to do is to use some C preprocessor machinery.
Let me explain through the example.
I have a header file which defines the macro
STR_CONST(name, value)
:The in my .h/.m pair where I want to define the constant I do the following:
et voila, I have all the information about the constants in .h file only.
我自己有一个标头,专门用于声明用于首选项的常量 NSString,如下所示:
然后在随附的 .m 文件中声明它们:
这种方法对我很有帮助。
编辑:请注意,如果在多个文件中使用字符串,则此方法效果最佳。 如果只有一个文件使用它,则只需在使用该字符串的 .m 文件中执行
#define kNSStringConstant @"Constant NSString"
即可。I myself have a header dedicated to declaring constant NSStrings used for preferences like so:
Then declaring them in the accompanying .m file:
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.对@Krizz的建议稍加修改,这样如果常量头文件包含在PCH中,它就可以正常工作,这是相当正常的。 由于原始文件被导入到 PCH 中,因此它不会将其重新加载到
.m
文件中,因此您不会得到任何符号,并且链接器会不满意。但是,以下修改使其可以工作。 这有点复杂,但它有效。
您将需要 3 个文件:包含常量定义的
.h
文件、.h
文件和.m 文件,我将分别使用
ConstantList.h
、Constants.h
和Constants.m
。Constants.h
的内容很简单:Constants.m
文件如下所示:最后,
ConstantList.h
文件具有实际的声明这就是全部:需要注意的几件事:
我必须在
.m
文件之后重新定义宏#undef
将其设置为要使用的宏。我还必须使用
#include
而不是#import
才能正常工作并避免编译器看到之前的预编译值。每当任何值发生更改时,这都需要重新编译您的 PCH(可能还包括整个项目),如果它们正常分离(和重复),则情况并非如此。
希望这对某人有帮助。
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.However, the following modification allows it to work. It's a bit convoluted, but it works.
You'll need 3 files,
.h
file which has the constant definitions, the.h
file and the.m
file, I'll useConstantList.h
,Constants.h
andConstants.m
, respectively. the contents ofConstants.h
are simply:and the
Constants.m
file looks like:Finally, the
ConstantList.h
file has the actual declarations in it and that is all: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.
Hope that is helpful for someone.
正如 Abizer 所说,您可以将其放入 PCH 文件中。 另一种不太脏的方法是为所有密钥创建一个包含文件,然后将其包含在您正在使用密钥的文件中,或者将其包含在 PCH 中。 将它们放在自己的包含文件中,这至少为您提供了一个位置来查找和定义所有这些常量。
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.
如果你想要全局常量之类的东西; 一种快速但肮脏的方法是将常量声明放入
pch
文件中。If you want something like global constants; a quick an dirty way is to put the constant declarations into the
pch
file.如果您喜欢命名空间常量,则可以利用结构, 星期五问答 2011-08-19:命名空间常量和函数
If you like namespace constant, you can leverage struct, Friday Q&A 2011-08-19: Namespaced Constants and Functions
尝试使用类方法:
我有时会使用它。
Try using a class method:
I use it sometimes.
我使用单例类,以便我可以模拟该类并在测试需要时更改常量。 常量类看起来像这样:
它的使用方式如下(注意使用常量 c 的简写 - 它可以节省每次键入
[[Constants alloc] init]
的次数):I use a singleton class, so that I can mock the class and change the constants if necessary for testing. The constants class looks like this:
And it is used like this (note the use of a shorthand for the constants c - it saves typing
[[Constants alloc] init]
every time):如果你想从 Objective c 调用类似 NSString.newLine; 的东西,并且你希望它是静态常量,你可以在 swift 中创建类似这样的东西:
你有很好的可读常量定义,并且可从您选择的类型中使用,同时又受类型上下文的限制。
If you want to call something like this
NSString.newLine;
from objective c, and you want it to be static constant, you can create something like this in swift:And you have nice readable constant definition, and available from within a type of your choice while stile bounded to context of type.