Reputation: 2087
What the difference between external variable of some sort and static variable?
//ClassA.m
NSString *var1;
static NSString *var2;
@implementation ClassA
...
Upvotes: 2
Views: 1743
Reputation: 104698
An extern
constant/variable is one which one definition may be accessed (or referenced) across multiple object files. It's a global, exported C symbol. Use this if you want access to the constant/global variable from multiple translation units (or compiled files) or if you want to use it in multiple binaries (e.g. you want to use it from your app, and the definition is in a dynamic library). You will typically declare this in the header for others to use.
The static
emits a copy for each translation. Each file that is compiled which also sees (e.g. is #include
d) the static will emit a copy of that static. You should avoid this. This will result in a bloated binary that has very confusing execution. You should favor the static if the value is local to a file, and should be private to that file.
For these reasons, you should favor static
in your .c, .m, .cpp, and .mm files, and extern
in your headers.
Finally, that NSString
pointer should be const
by default:
// declaration - file.h
extern NSString * const var1;
// definition - file.m
NSString * const var1 = @"var1";
or
static NSString * const var2 = @"var2";
If you still want more, here's a related answer I wrote, and here's another.
Upvotes: 3
Reputation: 53000
Global variables and static
Declaring a variable outside of any method (and in Objective-C either within, or outside, @implementation
/@end
makes the lifetime of the variable global, that is the variable will exist during the whole time period the application is executing.
A global variable with no qualification, or only with const
and/or volatile
qualifiers, is visible from anywhere. So for example:
NSString *MyApplicationName;
declares a global variable MyApplicationName
which can be accessed from any place in the application.
The visibility of a global variable (but not its lifetime) can be restricted to just the file (more accurately "compilation unit" allowing for one file including others) containing the declaration by qualifying it with static
. So for example:
static NSString *MyClassName;
declares a global variable MyClassName
which is only visible from the current compilation unit.
Using static
qualified global declarations within @implementation
/@end
is the closest thing Objective-C offers to other languages' "class variables".
You should not place global variable declarations, static
qualified or not, in header files as that would result in multiple distinct declarations - an error will result if there is no static
qualifier, and multiple distinct variables with different visibility scopes if there is one.
The extern
qualifier
The extern
qualifier does something rather different.
The original meaning (a small relaxation is now allowed, see below) is to just define the type and name of a global variable which is declared elsewhere. That is you are telling the compiler "there is a global variable of some type and name I'd like to use which will be supplied by another compilation unit". For example:
extern NSString *MyApplicationName;
states that some compilation unit contains the declaration (which must not be static
qualified):
NSString *MyApplicationName;
The extern
qualified declaration does not itself cause the allocation of any storage for the global variable.
You do place extern
qualified declarations in header files, this is how a compilation unit advertises the global variables it wishes to export. You can also place them in code files to reference globals variables declared elsewhere. Within a code file you can place an extern
qualified declaration either outside of any method/function - in which case the name/type is available for to whole compilation unit - or within a method/function - in which case the visibility of the name/type is limited to just that method/function.
The small relaxation
Originally you had to have one non-extern
qualifier declaration to satisfy any extern
qualified ones. However this was later changed, if on linking the various compilation units together none of them declare a global variable referenced by some extern
qualified declaration then the linker (usually?) just generates the variable itself and adds it to the resultant binary rather than producing a "missing global" error. Best programming practice is not to rely on this relaxation - always have a none-extern
qualified declaration for every global variable.
Upvotes: 2
Reputation: 7895
I could give an explanation, but it wouldn't be as good as this one:
http://blog.ablepear.com/2010/01/objective-c-tuesdays-static-variables.html
Upvotes: 1