views:

145

answers:

3

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.

+1  A: 

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.

TechZen
+1  A: 

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.

Kendall Helmstetter Gelner
A: 

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...

NSString * const kLabelNames[] = {
    @"Foo", @"Bar", @"Baz"
};

...and then you can write class methods like this one...

+ (NSArray *)labelNames
{
    static NSArray *names;
    if (names == nil) {
        names = [[NSArray alloc] initWithObjects:kLabelNames count:3];
    }
    return names;
}
jlehr