Search code examples
iosobjective-cnsarray

NSArray redefinition with a different type int & missing type specifier


The following code will not build and provides the warning of "Type specifier missing, defaults to 'int'" and the error "Redefinition of 'my_var' with a different type: 'int' vs 'NS Array *__strong'.

NSArray *my_var = nil;
my_var = @[
  @[@312, @"Name1"],
  @[@313, @"Name2"]
];

What am I missing? I've tried many different refactorings and for some reason cannot compile with a pre-defined NSArray.


Solution

  • You've put that code at global or file scope, outside of any function or method definition. You can't do that. The second assignment to my_var is only valid inside a function or method body. Outside of a function/method body, the compiler thinks the second line is another variable declaration, with a (default) type of int.

    You can't initialize my_var to an NSArray literal statically. A NSArray literal is different than a literal NSString. A literal NSString is created by the compiler and stored, fully usable, in the executable file. An NSArray literal turns into code that calls methods at runtime (under the covers) to create the array. That code is only allowed inside a function or method body.

    If you want a global constant NSArray, use a global function that creates the array once and returns it every time. Declare it in a .h file like this:

    NSArray *my_var();
    

    And define it in a .m file like this:

    NSArray *my_var() {
        static dispatch_once_t once;
        static NSArray *array;
        dispatch_once(&once, ^{
            array = @[
                @[@312, @"Name1"],
                @[@313, @"Name2"]
            ];
        });
        return array;
    }