22

How should I declare a global variable in my Objective-C project?

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
sri
  • 3,319
  • 7
  • 34
  • 48
  • 1
    You need to first consider whether they are necessary, and whether there is an elegant, or straightforward way to avoid them. – dreamlax Jul 30 '10 at 05:27

4 Answers4

33

Traditionally, global variables are declared in a header, and defined in a source file. Other source files only need to know how it is declared to use it (i.e. its type and its name). As long as the variable is defined somewhere in a source file, the linker will be able to find it and appropriately link all the references in other source files to the definition.

Somewhere in your header, you would declare a global variable like this:

extern int GlobalInt;

The extern part tells the compiler that this is just a declaration that an object of type int identified by GlobalInt exists. It may be defined later or it may not (it is not the compiler's responsibility to ensure it exists, that is the linker's job). It is similar to a function prototype in this regard.

In one of your source files, you define the GlobalInt integer:

int GlobalInt = 4;

Now, each file that includes the header will have access to GlobalInt, because the header says it exists, so the compiler is happy, and the linker will see it in one of your source files, so it too will be happy. Just don't define it twice!

However


You should consider whether or not this approach is useful. Global variables get messy for a number of reasons (trying to find out exactly where it is defined or declared, threading issues), there is usually not a need for global variables. You should perhaps consider using a singleton approach.

Community
  • 1
  • 1
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • 1
    A singleton is nothing more than a glorified global. Even better would be to explicitly pass the dependency to the object's constructor. – Michael Aaron Safyan Jul 30 '10 at 05:46
  • 4
    A singleton is more than a glorified global. Think about `NSUserDefaults`, `NSFileManager` etc. If the global can be implemented as a shared resource because it is truly atomic to the application then a singleton will work better than passing the same object around everywhere just to maintain context. – dreamlax Jul 30 '10 at 06:07
16

Don't. Global variables are often a sign of poor design. A common replacement in Objective-C is a class method that returns an object (that may or may not be a singleton), such as [NSUserDefaults standardUserDefaults] or [UIDevice currentDevice].

However, if you must use a global variable, read on.

In your header:

extern NSString *someString;
extern NSInteger someInteger;

In your implementation file:

NSString *someString = @"DEFAULT_VALUE";
NSInteger someInteger = DEFAULT_VALUE;
Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • +1 for the bolded "Don't." However, I must disagree with your recommendation of a class method or singleton. That is just disguising a global by wrapping it with a function. It would be far better to make the dependency explicit by requiring that the given object be passed to the init method. – Michael Aaron Safyan Jul 30 '10 at 05:47
  • That's even better, yes, but for certain uses a class method *does* present a viable alternative to a naked global. Globals aren't evil because everybody can see them; they're evil because they pollute the global namespace and allow for direct access to (and messing with) a variable. A class method solves both of those problems by restricting the symbol to the class' namespace and by abstracting away the data--the implementation can change without breaking code that uses it. – Jonathan Grynspan Jul 30 '10 at 06:04
  • There are plenty of legitimate cases of using a global var that have nothing to do with application design, like string constants for the application's copy grouped into a single file for easy translation, or constants for font names. In such cases, it would seem declaring a singleton would be the messier approach. – dclowd9901 Mar 10 '14 at 13:53
  • String constants are not what is meant by "globals." Globals are global *variables*, that is, symbols whose values can be changed. Constants are fine to give global scope to because you're not using them to encode any context-sensitive state. – Jonathan Grynspan Mar 21 '14 at 14:49
3

In my experience there are few instances when a program doesn't need, at least, some sort of data or utility/helper methods that can be accessed throughout the program.

They way I deal with this, rather than using global variables is to create what I call a 'project applicance', which is essentially just a class with a bunch of static methods.

It could be implemented multiple ways, but I use a singleton and just have the static methods call through to the single instance of the appliance class. For example, in my project Oovium I have:

Oovium.h:

@interface Oovium : NSObject {
    UIWindow* _window;
}

+ (UIWindow*) window;

Oovium.m:

@implementation Oovium

static Oovium* oovium;

- (UIWindow*) window {return _window;}

+ (void) initialize {
    oovium = [[Oovium alloc] init];
}

+ (UIWindow*) window {return [oovium window];}

I then include Oovium.h in my Oovium_Prefix.pch file so that it is automatically included in all of my files.

aepryus
  • 4,715
  • 5
  • 28
  • 41
0

Globals rock! I don't know what everyone is scared of. I used them successfully here.

Passing Data between View Controllers

Also used UIStepper to adjust values in another viewController. I could see them being an issue is larger programs, and in my opinion the singleton thing is just a masked global. Keep it simple, if your app is simple that is.

Community
  • 1
  • 1
  • 3
    Don't do this. Seriously, don't do it to just pass values between View Controllers. Read the accepted answer on the question instead. – Nef10 Jan 05 '18 at 21:56