When to use a static string vs. #define

I'm a little confused when it is best to use:

static NSString *AppQuitGracefullyKey = @"AppQuitGracefully"; 

instead

 #define AppQuitGracefullyKey @"AppQuitGracefully" 

I saw questions like this for C or C ++, and I think that it’s different here that it is specifically for Objective-C using an object, and on a device such as iPhone, there may be a stack, code space, or which I I don’t understand yet.

One use:

 appQuitGracefully = [[NSUserDefaults standardUserDefaults] integerForKey: AppQuitGracefullyKey]; 

Or is it just a matter of style?

Thank.

+44
objective-c cocoa-touch xcode cocoa
Jan 19 '10 at 8:12
source share
6 answers

If you use static code, the compiler will insert exactly one copy of the string into your binary and simple pointers to that string, which will result in more compact binaries. If you use #define, each use will have a separate copy of the string stored in the source. Continuous coalescence will handle many of the backup devices, but you make the linker work effortlessly.

+58
Jan 19 '10 at 8:16
source share

See "static const" vs "# define" vs "listing" . The main benefit of static is type safety.

In addition, the #define approach represents the flexibility of inline string concatenation that cannot be performed with static variables, for example.

 #define ROOT_PATH @"/System/Library/Frameworks" [[NSBundle bundleWithPath:ROOT_PATH@"/UIKit.framework"] load]; 

but this is probably not a very good style :).

+14
Jan 19 '10 at 8:30
source share

After some searching ( this question / answer, among other things), I think it’s important to say that anytime you use the string literal @"AppQuitGracefully" the string constant and no matter how many times you use it, it will point to that same object.

So, I think (and apologize if I am mistaken) that this sentence in the correct answer is incorrect: If you use a #define, there will be a separate copy of the string stored in the source on each use.

+4
Oct. 16 '12 at 10:25
source share

I would not recommend that you should use extern . Objective-c already defines FOUNDATION_EXPORT , which is more portable than extern , so the global NSString instance will look something like this:

.h

 FOUNDATION_EXPORT NSString * const AppQuitGracefullyKey; 

.m

 NSString * const AppQuitGracefullyKey = @"AppQuitGracefully"; 

I usually put them in declaration files (e.g. MyProjectDecl.h ) and import them when I need to.

There are several differences from these approaches:

  • #define has several disadvantages, for example, not a safe type. It’s true that there are workarounds for this (for example, #define ((int)1) ), but what is this point? And besides, there are debugging disadvantages of this approach. Compilers prefer constants. See this discussion.
  • static global variables are visible in the declared file.
  • extern makes the variable visible to all files. This contrasts with statics.

Static and external are distinguished by visibility. It is also noteworthy that none of these approaches duplicates a string (not even #define ), since the compiler uses String Interning to prevent this. In this NSHipster post, they show evidence:

 NSString *a = @"Hello"; NSString *b = @"Hello"; BOOL wtf = (a == b); // YES 

The == operator returns YES only if two variables point to the same instance. And, as you can see, it is.

Conclusion: use FOUNDATION_EXPORT for global constants. He debugs friendships and will be visible to your entire project.

+4
Jul 02 '15 at 12:38
source share

I use static when I need to export NSString characters from a library or frame. I use #define when I need a string in many places that I can easily change. In any case, the compiler and linker will take care of optimization.

+3
Jan 19 '10 at 8:29
source share

USING #define:

you cannot debug id value

Working with # define and other macros is a Pre-Processor job. When you first click Build / Run, it will process the source code, it will work with all macros (starting with the # character),

Suppose you created

 #define LanguageTypeEnglish @"en" 

and used it in two places in your code.

 NSString *language = LanguageTypeEnglish; NSString *languageCode = LanguageTypeEnglish; 

it will replace "LanguageTypeEnglish" with @"en" in all places. This way 2 copies of @"en" will be created. iee

 NSString *language = @"en"; NSString *languageCode = @"en"; 

Remember that before this process, the compiler is not in the picture.

After pre-processing all the macros, the compiler enters the image and it gets an input code like this,

 NSString *language = @"en"; NSString *languageCode = @"en"; 

and compile it.

USING static:

It respects the scope and is safe in type. you can debug id value

During compilation, if a compiler is found,

 static NSString *LanguageTypeRussian = @"ru"; 

then it checks whether the variable with the same name has been previously saved, if so, it will pass the pointer to this variable, if not, it will create this variable and pass it to the pointer, next time it will only pass the pointer of the same.

Thus, using static, only one copy of the variable is created within the scope.

+3
Dec 17 '14 at 8:00
source share



All Articles