In Objective-C, my understanding is that the directive @\"foo\" defines a constant NSString. If I use @\"foo\" in multiple places, the same immutable NSString object is referenc
I love all the answers here without a simple example of how to correctly declare one... so...
If you want the constant to be externally visible (ie. "global").... declare it as such in a header...
extern NSString *const MyTypoProneString;
and define it in a .m
file, OUTSIDE any @implementation
like...
NSString * const MyTypoProneString = @"iDoNtKnOwHoW2tYpE";
That said... if you simply want a static const
that IS LOCAL to your class' implementation (or even a certain method!)... simply declare the string INSIDE the implementation (or method) as...
static NSString *MavisBeacon = @"She's a freakin' idiot";
EDIT Although I do show how to do this... I have yet to be convinced that this style is in any way better than the ridiculously shorter, simpler, and less repetitive SINGLE declaration, á la..
#define SomeStupidString @"DefiningConstantsTwiceIsForIdiots"
Use #define
's... they are way less annoying.. Just don't let the preprocessor-player-haters get you down.
I assume it is to protect me from making a typo in the identifier name that the compiler wouldn't catch.
Correct. It's just basic defensive programming practice. The compiled result (hopefully) is the same either way.
But If so, couldn't I just:
#define kCellId @"CellId"
and avoid the static NSString * bit? Or am I missing something?
Yes. But the kCellId
symbol would be globally defined, at least in your compilation unit. Declaring a static variable makes the symbol local to that block.
You will typically see string constants defined as global variables or static variables rather than preprocessor defines. This helps ensure that you're only dealing with a single string instance between different compilation units.
It's good practice to turn literals into constants because:
I prefer using static const NSString*
static NSString* const
because it's slightly safer than #define
. I tend to avoid the preprocessor unless I really need it.
You should make the static variable const
.
One difference between static variable and a macro is that macros don't play well with debuggers. Macros also aren't type-safe.
Much of the static-var-vs-macro advice for C and C++ applies to Obj-C.
It is not guaranteed that when using @"foo"
in multiple places the runtime uses the same storage for them, and certainly may not be the case across compilation unit or library boundaries.
I would rather use static NSString *string = @"foo"
, especially with a lot of literal strings.
So, I'm coming into this a little late, but this has been asked numerous times in various ways in both the C / C++ areas of SO, but basically here's an expanded version of my comment to alex gray:
Anytime you think you should use a #define for string macros, you mostly likely shouldn't. The reason is because #define macros are basically regex replacements to the preprocessor. Anytime the preprocessor sees a macro called, it replaces it with whatever you defined. This means a new string literal every single time will get allocated into memory, which is really bad in places like cell reuse identifiers (thus why Apple's UITableViewController default code uses a static).
Using extern / static const instead points all references to a single place in memory, as Eonil mentioned. This is much more memory efficient and performant, which is very important on mobile devices.