Ily*_*ski 16 constants objective-c
我想在objective-c中定义一个常量.
以前我有以下功能:
+(NSString *) getDocumentsDir {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex: 0];
paths = nil;
return documentsDir;
}
Run Code Online (Sandbox Code Playgroud)
我想只定义一个常量"Documents_Dir" - 当函数被调用时,之后访问以前创建的值.
我尝试了以下代码,但没有用:
#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 \
} \
Run Code Online (Sandbox Code Playgroud)
我对预编译器指令不太满意,所以任何帮助都将不胜感激.
Qui*_*lor 34
序言:理解预编译器指令和真实常量之间的区别是值得的.一个#define
只是做一个文本替换编译器生成的代码之前.这对于数值常量和typedef很有用,但对于函数或方法调用并不总是最好的想法.我假设您确实需要一个真正的常量,这意味着创建搜索路径的代码应该只执行一次.
在MyClass.m文件中,定义变量并将其填充到如下+initialize
方法中:
static NSArray *documentsDir;
@implementation MyClass
+ (void) initialize {
if (documentsDir == nil) {
documentsDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES) lastObject] retain];
}
}
...
@end
Run Code Online (Sandbox Code Playgroud)
该static
修饰使得它只有在它被声明的编译单元可见.对于一个简单的常数,这就是你所需要的.
如果该类具有子类,+initialize
则将为每个子类调用一次(默认情况下),因此您需要在分配之前检查是否documentsDir
存在nil
,因此不会泄漏内存.(或者,正如Peter Lewis指出的那样,您可以使用其中一个==
或-isMemberOfClass:
方法检查当前正在初始化的类是否为MyClass .)如果子类还需要直接访问常量,则需要预先声明变量如extern
在MyClass.h文件(其子类包括):
extern NSArray *documentsDir;
@interface MyClass : NSObject
...
@end
Run Code Online (Sandbox Code Playgroud)
如果将变量预先声明为extern,则必须从定义中删除static
关键字以避免编译错误.这是必要的,因此变量可以跨越多个编译单元.(啊,C的乐趣...)
注:在Objective-C代码,更好的方式来声明作为东西extern
是用OBJC_EXPORT
(一#define
宣布<objc/objc-api.h>
,其基于集合的您是否正在使用C++).只需更换extern
,OBJC_EXPORT
你就完成了.
编辑:我刚刚发生了一个相关的问题.
Pet*_*wis 12
最简单的解决方案是将路径更改为静态变量并仅将其评估一次,如下所示:
+(NSString *) getDocumentsDir {
static NSString *documentsDir = nil;
if ( !documentsDir ) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
documentsDir = [paths objectAtIndex: 0];
}
return documentsDir;
}
Run Code Online (Sandbox Code Playgroud)
"static"告诉编译器documentsDir实际上是一个全局变量,尽管只能在函数内访问.因此它被初始化为nil,并且第一次调用getDocumentsDir将重新评估它,然后进一步调用将返回预先评估的值.
归档时间: |
|
查看次数: |
26457 次 |
最近记录: |