1

While reading this blog the writer says that

NSArray *array = @[ @"one", @"two" ];

if the above array is a global variable, then it errors out. The reason is

This is because the @[] syntax literally translates into a call to an NSArray method. The compiler can't compute the result of that method at compile time, so it's not a legal initializer in this context.

My question is how can the same declaration inside a method is valid?

Sandeep
  • 7,156
  • 12
  • 45
  • 57

2 Answers2

6

The array literal syntax is translated to:

NSString *vals[2] = { @"one", @"two" };
[NSArray arrayWithObjects:vals count:2];

Globals and statics can only be initialized with compile time constants. The above is not a compile time constant. It can only be evaluated at runtime.

A regular variable can be initialized at runtime so the value does not need to be a compile time constant.

One option for a static or global is to initialize it in the initialize method of the class:

static NSArray *array = nil;

+ (void)initialize {
    if (self == [ThisClass class]) {
        array = @[ @"one", @"two", nil];
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Strictly speaking, it is not `arrayWithObjects`, but `arrayWithObjects:count:`. There are subtle differences, compare http://stackoverflow.com/a/14527582/1187415. – Martin R Mar 27 '13 at 03:52
1

I'm not entirely sure, but I would guess that while global variables must be able to be initialized at compile time, and thus the compiler must be able to compute it, variables inside of methods aren't computed until runtime, and thus can use that syntax.

Jimmy Lee
  • 1,001
  • 5
  • 12