在Objective-C中定义一个常量 [英] Defining a constant in objective-c

查看:81
本文介绍了在Objective-C中定义一个常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Objective-c中定义一个常量.

I want to define a constant in objective-c.

以前,我具有以下功能:

Previously I had the following function:

+(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指出的那样,您可以使用==

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中定义一个常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆