views:

5339

answers:

6

how can i declare a global NSArray and then use it across my app?

+7  A: 

There are a couple different ways you can do this:

  1. Instead of declaring it as a global variable, wrap it in a singleton object, then have the singleton by available anywhere (by #importing the .h file)

  2. Create a .h file, like "Globals.h". In the .h, declare your array as static extern NSMutableArray * myGlobalArray; Then in the somewhere else in your app (the AppDelegate is a good place), just do: myGlobalArray = [[NSMutableArray alloc] init]; Then anywhere you need the array, just #import "Globals.h"

  3. This is like #2, but without the global header. You can define your array as static extern NSMutableArray *myGlobalArray; inside the #ifdef __OBJC__ block of your project's .pch file. The .pch file is a header file that is automatically #imported into every file in your project.

There are pros and cons of each approach. I've used all three at varying times in varying circumstances. I would say the singleton approach is probably the most proper, since it would be most flexible for initialization, access restriction, and memory management. However, it can be unnecessary if you don't need that.

Option #2 is nice if you have lots of "global" variables that you don't want to expose to every file across your project. You can just #import it where its needed. However, this approach (as well as #3) disassociates the declaration from the initialization (ie, the object is not created near where it's declared). Some might argue this is not proper, and they might be correct.

Option #3 is nice because then you never have to remember to #import anything at all. However, it raises the same questions as option #2.

Dave DeLong
+5  A: 

A 4th answer is to declare the array in your UIApplicationDelegate and access it through

[[[UIApplication sharedApplication] delegate] myArray];

For times when I just need a handful of global objects, I found this is the easiest and cleanest way to do it.

kubi
+1 This is also a good approach. The only caveat this has is that it'll produce a compiler warning, since -[UIApplication delegate] returns an object of type id<UIApplicationDelegate>, which does not have a "myArray" method. The solution would be to cast it, but that makes the line somewhat more difficult to ready: `[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] myArray];`
Dave DeLong
Plus, casting it means you would also need to #import the MyAppDelegate header file.
Dave DeLong
+1  A: 

If you're considering storing some kind of shared preferences for your app, use [NSUserDefaults sharedDefaults] to persist simple data which can be used across app. If you're storing transient data, then the 'static' approach will work as elsewhere.

However it's probably better to use a singleton object approach with a class accessor, like NSUserDefaults, and then provide instance accessor methods to acquire your data. That way, you'll isolate yourself from potential data structure changes in the future. You'd then use a static var, as above, but within the .m file (and hence you don't need the 'extern' definition). It would typically look like:

static Foo *myDefault = nil;
@implementation Foo
+(Foo)defaultFoo {
  if(!myDefault)
    myDefault = [[Foo alloc] init]; // effective memory leak
  return myDefault;
}
@end

You'd then have instance accessors, and use them as [[Foo defaultFoo] myArray] which can be accessed from any part of the app, and without any compile time errors.

AlBlue
A: 

I am new to Objectice C, but have found this post particularly helpful when defining global arrays. However, when going with option #2 I get an error back in the implementation file ".m" right beneath #import "Globals.h" saying "expected specifier-qualifier-list before 'static' ." this makes me think there is something wrong with the .h file. thoughts???

mark
A: 

Everyone here seems to have an implicit, omitted first line: "You can do it K&R C-style, or..."

Yes, you can still do it C-style.

In file 1: NSArray *MyArray;

In file 2: extern NSArray *MyArray;

Playing Captain Obvious here.

Seva Alekseyev
A: 

I appreciate the continued help. Would you mind showing me what the .h, .m, and appdelegate file would look like for option #2?? I am still getting errors.

mark