Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static NSString usage vs. inline NSString constants

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

Why do I see this code snippet so often (for example in UITableViewCell reuse):

static NSString *CellId = @"CellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellId];

Instead of just:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId"];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"CellId"];

I assume it is to protect me from making a typo in the identifier name that the compiler wouldn't catch. But If so, couldn't I just:

#define kCellId @"CellId"

and avoid the static NSString * bit? Or am I missing something?

like image 418
Trashpanda Avatar asked Dec 21 '09 01:12

Trashpanda


4 Answers

It's good practice to turn literals into constants because:

  1. It helps avoid typos, like you said
  2. If you want to change the constant, you only have to change it in one place

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.

like image 137
Tom Dalling Avatar answered Nov 12 '22 10:11

Tom Dalling


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.

like image 37
Alex Gray Avatar answered Nov 12 '22 10:11

Alex Gray


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.

like image 9
outis Avatar answered Nov 12 '22 09:11

outis


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.

like image 3
apaderno Avatar answered Nov 12 '22 11:11

apaderno