views:

96

answers:

3

First off, I've seen this question and understand why the following code doesn't work. That is not my question.

I have a constant, which is declared like;

//Constants.h
extern NSString * const MyConstant;

//Constants.m
NSString * const MyConstant = @"MyConstant";

However, in certain contexts, it's more useful to have this constant have a much more descriptive name, like MyReallySpecificConstant. I was hoping to do:

//SpecificConstants.h
extern NSString * const MyReallySpecificConstant;

//SpecificConstants.m
#import "Constants.h"
NSString * const MyReallySpecificConstant = MyConstant;

Obviously I cannot do this (which is explained in the linked question above).

My question is:

How else (besides something like #define MyReallySpecificConstant MyConstant) can I provide a single constant under multiple names?

+3  A: 

In general, the compiler will fold identical string constants into the same strings unless you tell it not to. Even though you cannot initialize one constant with another, initializing them both with the same value will have the same net effect.

//Constants.h
extern NSString * const MyConstant;
extern NSString * const MyOtherConstant;

//Constants.m
#define MyConstantValue "MyConstant"
NSString * const MyConstant = @MyConstantValue;
NSString * const MyOtherConstant = @MyConstantValue;

You hide the #define in one source file instead of in a header. You only have to change the value in one place. You have two names for one constant. Of course, in your scenario with constants defined in multiple files, you would have to have the #define accessible to those source files.

drawnonward
+1 I like this option, since it allows me to keep my `const` modifier, but still only have the actual string value in one place.
Dave DeLong
+4  A: 

My first reaction to your question was a question in return - Is the fact that you want to have a constant under multiple names, an indicator that the name of the constant needs rethinking in the first place?

Derek Clarkson
+1 this is a very good point, and one I should probably be considering. However, at this point I need to use the same values.
Dave DeLong
+1  A: 

Assign your string constants in code:

//Constants.h
extern NSString * MyConstant;
extern NSString * MyOtherConstant;
void setUpConstants();

//Constants.m
NSString * MyConstant;
NSString * MyOtherConstant;
NSString * const ValueOfString = @"A Value";
void setUpConstants()
{
    MyConstant = ValueOfString;
    MyOtherConstant = ValueOfString;
}

One downside if that they are not protected by the compiler against modification. However the initialization is very flexible and you maybe be able to improve other code. You also guarantee different addresses for your strings, whether or not the compiler decides that folding is what it does this week.

Steve Weller
+1 I think if I were to go this route, I'd probably do the initialization in an `__attribute__ ((constructor))` function so that it happens automatically when the code is loaded.
Dave DeLong