Constants in Objective-C

Viewed 441293

I'm developing a Cocoa application, and I'm using constant NSStrings as ways to store key names for my preferences.

I understand this is a good idea because it allows easy changing of keys if necessary.
Plus, it's the whole 'separate your data from your logic' notion.

Anyway, is there a good way to make these constants defined once for the whole application?

I'm sure that there's an easy and intelligent way, but right now my classes just redefine the ones they use.

14 Answers

You should create a header file like:

// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.

(You can use extern instead of FOUNDATION_EXPORT if your code will not be used in mixed C/C++ environments or on other platforms.)

You can include this file in each file that uses the constants or in the pre-compiled header for the project.

You define these constants in a .m file like:

// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";

Constants.m should be added to your application/framework's target so that it is linked in to the final product.

The advantage of using string constants instead of #define'd constants is that you can test for equality using pointer comparison (stringInstance == MyFirstConstant) which is much faster than string comparison ([stringInstance isEqualToString:MyFirstConstant]) (and easier to read, IMO).

Easiest way:

// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"

Better way:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

One benefit of the second is that changing the value of a constant does not cause a rebuild of your entire program.

There is also one thing to mention. If you need a non global constant, you should use static keyword.

Example

// In your *.m file
static NSString * const kNSStringConst = @"const value";

Because of the static keyword, this const is not visible outside of the file.


Minor correction by @QuinnTaylor: static variables are visible within a compilation unit. Usually, this is a single .m file (as in this example), but it can bite you if you declare it in a header which is included elsewhere, since you'll get linker errors after compilation

As Abizer said, you could put it into the PCH file. Another way that isn't so dirty is to make a include file for all of your keys and then either include that in the file you're using the keys in, or, include it in the PCH. With them in their own include file, that at least gives you one place to look for and define all of these constants.

If you want something like global constants; a quick an dirty way is to put the constant declarations into the pch file.

If you want to call something like this NSString.newLine; from objective c, and you want it to be static constant, you can create something like this in swift:

public extension NSString {
    @objc public static let newLine = "\n"
}

And you have nice readable constant definition, and available from within a type of your choice while stile bounded to context of type.

Related