views:

282

answers:

4

I'm attempting to create an NSArray with a grouping of string literals, however I get the compile error "Initializer element is not constant".

NSArray *currencies = [NSArray arrayWithObjects:@"Dollar", @"Euro", @"Pound", nil];

Could someone point out what I'm doing wrong, and possibly explain the error message?

A: 

There's nothing wrong with that code. Are you sure the error is being produced at that line?

Dave DeLong
A: 

I'm a newbie in objective-c, but I think that the correct code is:

NSArray *currencies = [[NSArray alloc] initWithObjects:@"Dollar", @"Euro", @"Pound", nil];

I am not sure tho.

Adirael
That is also valid, however there is nothing wrong with OP's code. Your method simply retains the array whereas his does not
pheelicks
Good to now, thanks :)
Adirael
However, if the object stored in a static variable is **not** retained, it's a lurking crasher bug, so alloc/init would be the right thing to do.
jlehr
+5  A: 

This isn't a problem with the NSArray creation itself (you would get the same error if you wrote [NSArray array] instead), but with where you've written it. I'm guessing this is a global or file-static NSArray. In C, that kind of variable has to have a constant initializer — meaning not a function call (or, by extension, a method call). The solution is to put the actual creation and assignment of the array into a method that will be called before you need the array, such as initialize.

Chuck
+1 this didn't even occur to me. I think I just assumed that the code was in the proper location. :)
Dave DeLong
I had declared this in the header file, but was unaware that I could not initialize this outside of a method.
Kyle
+1  A: 

It sounds like Chuck has spotted the problem. One thing you want to be aware of though in coding your solution is that you'll want to avoid storing an autoreleased instance of NSArray in a static variable. Also, a common pattern for these situations is to write a class method that creates and returns the value stored in the static variable, like so:

+ (NSArray *)currencies
{
    static NSArray *_currencies;

    // This will only be true the first time the method is called...
    //
    if (_currencies == nil)
    {
        _currencies = [[NSArray alloc] initWithObjects:@"Dollar", @"Euro", @"Pound", nil];
    }

    return _currencies;
}
jlehr