Defining a constant in objective-c(在objective-c中定义一个常数)
问题描述
我想在objective-c中定义一个常量.
I want to define a constant in objective-c.
以前我有以下功能:
+(NSString *) getDocumentsDir {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex: 0];
paths = nil;
return documentsDir;
}
我只想定义一个常量Documents_Dir"一次 - 当函数被调用时,然后访问之前创建的值.
I'd like to define a constant "Documents_Dir" only once - when the function gets called and after that to access a previously created value.
我尝试了以下代码,但没有成功:
I've tried the following code, which didn't work:
#define getDocumentsDir
{
#ifdef Documents_Dir
return Documents_Dir;
#else
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex: 0];
#define Documents_Dir [paths objectAtIndex: 0];
paths = nil;
return Documents_Dir;
#endif
}
我不擅长预编译器指令,因此我们将不胜感激.
I am not strong with precompiler directives, so any help will be appreciated.
推荐答案
前奏: 了解预编译器指令和真正的常量之间的区别是值得的.#define
只是在编译器构建代码之前进行文本替换.这对于数值常量和 typedef 非常有用,但对于函数或方法调用并不总是最好的主意.我在假设您确实想要一个真正的常量的情况下进行操作,这意味着创建搜索路径的代码应该只执行一次.
Prelude: It pays to understand the difference between precompiler directives and true constants. A #define
just does a text replacement before the compiler builds the code. This works great for numerical constants and typedefs, but is not always the best idea for function or method calls. I'm operating under the assumption that you really want a true constant, meaning that the code to create the search path should only be executed once.
在您的 MyClass.m 文件中,定义变量并在 +initialize
方法中填充它,如下所示:
In your MyClass.m file, define the variable and populate it in an +initialize
method like so:
static NSArray *documentsDir;
@implementation MyClass
+ (void) initialize {
if (documentsDir == nil) {
documentsDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES) lastObject] retain];
}
}
...
@end
static
修饰符使其仅在声明它的编译单元中可见.对于一个简单的常量,这就是你所需要的.
The static
modifier makes it visible only within the compilation unit where it is declared. For a simple constant, this is all you need.
如果类有子类,+initialize
将为每个子类调用一次(默认情况下),因此您需要检查 documentsDir
是否为 nil
在分配给它之前,所以你不会泄漏内存.(或者,正如 Peter Lewis 指出的那样,您可以使用 ==
或 -isMemberOfClass:
方法.)如果子类也需要直接访问常量,则需要在 MyClass.h 文件中将变量预先声明为 extern
(其中子类包括):
If the class has subclasses, +initialize
will be called once for each subclass (by default), so you'll want to check whether documentsDir
is nil
before assigning to it, so you don't leak memory. (Or, as Peter Lewis points out, you can check if the class currently being initialized is the MyClass, using either ==
or the -isMemberOfClass:
method.) If the subclasses also need to access the constant directly, you'd need to pre-declare the variable as extern
in MyClass.h file (which the child classes include):
extern NSArray *documentsDir;
@interface MyClass : NSObject
...
@end
如果您将变量预先声明为 extern,则必须从定义中删除 static
关键字,以避免编译错误.这是必要的,因此变量可以跨越多个编译单元.(啊,C的快乐……)
If you pre-declare the variable as extern, you must remove the static
keyword from the definition to avoid compile errors. This is necessary so the variable can span multiple compilation units. (Ah, the joys of C...)
注意:在 Objective-C 代码中,将某些内容声明为 extern
的更好方法是使用 OBJC_EXPORT
(在
中声明的 #define
)根据您是否使用 C++ 设置.只需将 extern
替换为 OBJC_EXPORT
即可.
Note: In Objective-C code, the better way to declare something as extern
is to use OBJC_EXPORT
(a #define
declared in <objc/objc-api.h>
) which is set based on whether or not you're using C++. Just replace extern
with OBJC_EXPORT
and you're done.
我刚刚遇到了一个相关的SO问题.
这篇关于在objective-c中定义一个常数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在objective-c中定义一个常数
基础教程推荐
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01