如何使用 NSArray 作为全局常量?
我使用一组 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”也不起作用。这是因为我的数组中的字符串不是常量吗?
如何将数组设置为全局常量?谢谢。
I'm using a set of Constant.m
files, one per target, to define specific things for each target. For example:
// Constants.h
extern NSString * const kDatabaseFileName;
//Constants.m
NSString * const kDatabaseFileName = @"target_one.sqlite";
I'd also like to define an NSArray for each of my targets:
NSArray * const kLabelNames = [[NSArray alloc] initWithObjects:
@"nameLabel", @"addressLabel", nil];
But this gives "error: initializer element is not constant". Using 'arrayWithObjects` doesn't work either. Is this because the strings in my array are not constants?
How can I set up an array as a global constant? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您应该创建一个包含类方法中的常量的类。然后,您可以将该类添加到任何目标并调用方法来获取数组等对象中的常量。改变类或类实现来更改常量的返回。
如果您经常使用它,您可以创建一个定义方法名称的协议。然后交换每个目标中实现协议的类,以便相同的代码根据需要返回不同的值。
You should create a class that contains the constants in class methods. Then you can add the class to whatever target and call the methods to get constants in objects like arrays. Vary the class or the class implementation to change the return of the constants.
If you use it a lot, you can create a protocol that defines the method names. Then swap out the class that implements the protocol in each target so that the same code returns different values as need.
如果您想避免对每次使用进行 NULL 检查,您可以子类化 NSObject +initialize 方法。第一次实例化您的类时,它将被调用一次(如果实例化了任何子类,则每个子类都会调用一次),并且是进行此类初始化的非常好的地方。
If you want to avoid doing a NULL check on each usage, you can subclass the NSObject +initialize method. That will get called once, the first time your class is instantiated (and once more per subclass, if any subclasses are instantiated), and is a very good place to do this sort of initialization.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html%23//apple_ref/occ/clm/NSObject/initialize
在 Objective-C 中,对象只能在堆中分配,因此无法在静态内存中创建 NSArray。但是,您可以像这样创建一个指向 NSString 常量的指针的 C 数组...
...然后您可以编写像这样的类方法...
编辑
请注意,随着新技术的引入例如 ARC、Grand Central Dispatch 和数组的新文字语法,现在有一种更直接的方法来完成类似的事情。请注意,下面的示例还提供了更高的线程安全性,尽管原始示例可以合并 @synchronized 块或其他几种机制之一来实现类似的结果。
然而,上面的例子并没有完全解决最初的问题。如果确实需要全局常量数组,则可以按照与原始答案类似的方式重写前面的示例,同时仍然利用 GCD:
In Objective-C, objects can only be allocated in heap, so there's no way to create an NSArray in static memory. However, you can create a C array of pointers to NSString constants like so...
...and then you can write class methods like this one...
Edit
Note that with the introduction of new technologies such as ARC, Grand Central Dispatch and the new literal syntax for arrays, there's now a more straightforward way to accomplish something similar. Note that the example below also provides greater thread safety, though the original example could have incorporated an
@synchronized
block, or one of several other mechanisms, to achieve similar results.However the above example doesn't completely address the original question though. If a global constant array is truly needed, the preceding example could be rewritten along similar lines as the original answer, while still taking advantage of GCD:
这是一个更简单的方法:
使用逗号分隔的元素(或任何您想要的分隔符)声明 NSString
,然后在需要时转换为 NSArray:
Here's a much simpler approach:
Declare NSString with comma separated elements (or whatever delimiter you want)
Then convert to NSArray whenever you need it:
如果您想要一组包含 NS 类型的常量,请考虑将它们全部放在一个单例中。
您可以有一个头文件和多个实现文件(每个目标一个)。只要所有这些都实现了头文件中声明的类,就应该没问题。
If you want a set of constants that includes NS types, consider placing them all in a singleton.
You could have a single header file, and multiple implementation files (one per target). As long as that all implement the class declared in the header file you should be fine.
使用宏:
Use a macro: