Iphone 如何将NSArray用作全局常量?
我使用一组Iphone 如何将NSArray用作全局常量?,iphone,objective-c,arrays,constants,global,Iphone,Objective C,Arrays,Constants,Global,我使用一组Constant.m文件,每个目标一个,为每个目标定义特定的内容。例如: // Constants.h extern NSString * const kDatabaseFileName; //Constants.m NSString * const kDatabaseFileName = @"target_one.sqlite"; 我还想为我的每个目标定义一个NSArray: NSArray * const kLabelNames = [[NSArray alloc] initWi
Constant.m
文件,每个目标一个,为每个目标定义特定的内容。例如:
// Constants.h
extern NSString * const kDatabaseFileName;
//Constants.m
NSString * const kDatabaseFileName = @"target_one.sqlite";
我还想为我的每个目标定义一个NSArray:
NSArray * const kLabelNames = [[NSArray alloc] initWithObjects:
@"nameLabel", @"addressLabel", nil];
但这会导致“错误:初始值设定项元素不是常量”。使用“arrayWithObjects”也不起作用。这是因为数组中的字符串不是常量吗
如何将数组设置为全局常量?谢谢。您应该创建一个包含类方法中常量的类。然后,您可以将该类添加到任何目标,并调用这些方法来获取对象(如数组)中的常量。更改类或类实现以更改常量的返回
如果您经常使用它,您可以创建一个定义方法名称的协议。然后交换在每个目标中实现协议的类,以便相同的代码根据需要返回不同的值如果你想要一组包含NS类型的常量,考虑把它们都放在一个单体中。
您可以有一个头文件和多个实现文件(每个目标一个)。只要实现了头文件中声明的类,就可以了。在Objective-C中,对象只能在堆中分配,因此无法在静态内存中创建NSArray。但是,您可以创建指向NSString常量的指针的C数组,如下所示
NSString * const kLabelNames[] = {
@"Foo", @"Bar", @"Baz"
};
…然后您可以编写像这样的类方法
+ (NSArray *)labelNames
{
static NSArray *names;
if (names == nil) {
names = [[NSArray alloc] initWithObjects:kLabelNames count:3];
}
return names;
}
编辑
请注意,随着ARC、Grand Central Dispatch和新的数组文字语法等新技术的引入,现在有了一种更直接的方法来完成类似的任务。请注意,下面的示例还提供了更高的线程安全性,尽管原始示例可以合并一个@synchronized
块或其他几种机制之一,以实现类似的结果
+ (NSArray *)labelNames
{
static NSArray *names;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
names = @[@"Foo", @"Bar", @"Baz"];
});
return names;
}
然而,上面的例子并没有完全解决最初的问题。如果确实需要一个全局常量数组,则可以按照与原始答案类似的行重写前面的示例,同时仍然利用GCD:
NSString * const kLabelNames[] = {
@"Foo", @"Bar", @"Baz"
};
+ (NSArray *)labelNames
{
static NSArray *names;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
names = [NSArray arrayWithObjects:kLabelNames count:3];
});
return names;
}
如果您想避免对每个用法进行空检查,可以将NSObject+initialize方法子类化。第一次实例化类时(如果实例化了任何子类,则每个子类都会调用一次),这将是进行此类初始化的一个非常好的地方
这里有一个更简单的方法: 使用逗号分隔的元素(或任何您想要的分隔符)声明NSString 然后在需要时转换为NSArray:
NSArray *namesArray = [kLabelNames componentsSeparatedByString:@","];
使用宏:
#define SOME_ARRAY (@[@"blah", @"asdf", @"qwerty"])
如果仔细阅读链接文档,您会发现
initialize
可以(而且经常)调用多次:“运行时在类或从它继承的任何类从程序内部发送第一条消息之前,向程序中的每个类发送initialize
一次。”[emphasis added]如果您想用一个动态值替换count:3,那么您可以使用传统的C方法获得数组的大小。count:sizeof(kLabelNames)/sizeof(kLabelNames[0])
#define SOME_ARRAY (@[@"blah", @"asdf", @"qwerty"])