0

I'm trying to initialize global variables, however I'm not sure what I'm doing wrong, as I get an error.

Right now, I have a Globals.h file that I import into my AppDelegate. Here, I declare:

#ifndef Globals_h
#define Globals_h

#endif /* Globals_h */

extern NSArray *CompetencyOne;
extern NSArray *CompetencyTwo;
extern NSArray *CompetencyThree;
extern NSArray *CompetencyFour;
extern NSArray *CompetencyFive;
extern NSArray *CompetencySix;
extern NSArray *CompetencySeven;
extern NSArray *CompetencyEight;
extern NSArray *CompetencyNine;
extern NSArray *CompetencyTen;
extern NSArray *CompetencyEleven;
extern NSArray *CompetencyTwelve;
extern NSArray *Competencies;

Then, I'm not sure where to define these arrays. I tried in AppDelegate.m in the didFinishWithLaunchingOptions method, and the ViewController's viewDidLoad method, and I created a separate method,

-(void) initializeCompetencies{ <arrays with values>} 

in the ViewController, but I keep getting the same error:

Undefined symbols for architecture x86_64:
  "_Competencies", referenced from:
  -[QuestionViewController viewDidLoad] in QuestionViewController.o
  -[QuestionViewController changed:] in QuestionViewController.o
  -[QuestionViewController nextMilestone:] in QuestionViewController.o
  -[QuestionViewController pressBack:] in QuestionViewController.o
  -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyEight", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyEleven", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyFive", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyFour", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyNine", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyOne", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencySeven", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencySix", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyTen", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyThree", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyTwelve", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyTwo", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Any ideas how to properly declare and initialize global arrays? Or, how to fix this error? Thank you!

4 Answers4

2

Objective-C objects are, with the exception of NSString constants, only ever created at runtime, thus you can't use an expression to initialize them otherwise you'll get error: initializer element is not a compile-time constant

If you declare:

//Globals.h
extern NSArray *CompetencyOne;

//Globals.m
NSArray *CompetencyOne = nil; //this works coz nil is compile time constant

Please check out the link

Community
  • 1
  • 1
Anni S
  • 1,996
  • 19
  • 28
  • The `= nil` is actually not necessary because all "objects of static storage duration" are initialized to zero. That's from the C standard. – Nikolai Ruhe Nov 08 '15 at 09:13
0

Declaring and initializing is not enough. You also have to define the variables.

Add a Globals.m file and copy the declarations, removing extern:

// Globals.m:

NSArray *CompetencyOne;
NSArray *CompetencyTwo;
NSArray *CompetencyThree;
...
Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • Thanks. Ok, I have a Globals.m file with a method -(void) initializeCompetencies { }. Now, how do I get that info to my viewController? – Nadir Bilici Nov 06 '15 at 20:45
  • Your Globals.m should simply have the arrays declared at the top of the class, i.e NSArray *CompetencyOne = @{....}; – davbryn Nov 06 '15 at 21:14
0

Sooo, arrays are tricky because they're not compile time constants. You'll have to do this:

Constants.h

extern NSArray *myArray;

Constants.m

NSArray *myArray = nil;

Then, somewhere on app initialize, probably app delegate did finish launching call your function:

myArray = @[@1, @2, @3];
Logan
  • 52,262
  • 20
  • 99
  • 128
  • Thanks for the heads up Logan. To clarify, where in the .h and .m do I declare and initialize the arrays? – Nadir Bilici Nov 06 '15 at 21:18
  • Declare the arrays anywhere directly in the file, then initialize maybe in a global function called from app delegate did finish launching – Logan Nov 06 '15 at 22:07
0

This sounds more like you want an object to create immutable arrays for consumption within the app.

How about a class called CompentencyFactory that has a bunch of static methods:

+ (NSArray *) competencyOne;
+ (NSArray *) competencyTwo;

etc that look like this:

+ (NSArray *) competencyOne {
    return @[
        @"foo",
        @"bar",
        @"fubnut"
    ];
}

That you can reference throughout the app like:

NSArray *comp = [CompetencyFactory competencyOne];
davbryn
  • 7,156
  • 2
  • 24
  • 47