Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I declared this array in my view controller implementation file:

NSMutableArray *images = [NSMutableArray array];

I wanted an empty, mutable array that I would later add UIImageViews to. It always return the error:

initializer element is not constant
share|improve this question
    
Show how (where) you declared images. Most likely it is a global or static variable so you can't assign the value like you are. –  rmaddy Jul 19 '13 at 0:52
    
Maybe the code is static NSMutableArray* images= [NSMutableArray array]? –  Ramy Al Zuhouri Jul 19 '13 at 0:53
    
im a noobie programmer. So one, this is the only place that images is declared, and two: should this be in the view controller class even? –  user1624992 Jul 19 '13 at 1:04
    
@user1624992 But where exactly is this line of code? Show some context. Is this before the @implementation line? After? If after, is it inside curly braces or not? –  rmaddy Jul 19 '13 at 1:13
    
ahh, I see the problem; Its not in a function, its just after the @implementation... line. I need to put it in a function or something. In that case, how would I make it available to other functions (global)? –  user1624992 Jul 19 '13 at 1:34

3 Answers 3

The proper solution is to make images an instance variable and then you initialize it in your init method.

@implementation SomeClass {
    NSMutableArray *images; // instance variable
}

- (id)init {
    self = [super init];
    if (self) {
        images = [[NSMutableArray alloc] init];
    }

    return self;
}

This is an example. If you have a specific init... method, use that instead.

As an instance variable, other methods in the class now have access to images and each instance of the class gets its own copy of images.

share|improve this answer
    
Do I need setters and getters for images? –  user1624992 Jul 19 '13 at 21:34
    
"Need" - no. Though the general recommendation is to create a property. If images is only used within the class then create a private property declared in a class extension in the .m file. If other classes need access then you should add a public property in the .h file. –  rmaddy Jul 19 '13 at 21:37

You need to show more code, but the problem is pretty obvious if that really is the line that is erroring out.

You can only dynamically initialization variables at the time of declaration in very specific spots. Dynamically includes calling a method.

NSMutableArray *a = [NSMutableArray array]; // this will error.
static NSMutableArray *a = [NSMutableArray array]; // this will error.
@implementation Booger
{
      NSMutableArray *a = [NSMutableArray array]; // this will error
}
NSMutableArray *a = [NSMutableArray array]; // this will error.
- (void)bar
{
   NSMutableArray *a = [NSMutableArray array]; // this is fine
}

Sounds like you need to dive a bit more deeply on the whole object-oriented thing. A class is a collection of functions called methods that either operate on the class (class methods) or a single instance of the class (instance methods). An instance can store state that is accessible to all methods when any method is invoked on that instance. In traditional OO, such state is stored in instance variables. Typically, you would define a pair instance methods that set and get that instance variable's value. These are called accessors or setter/getter. In modern Objective-C, we use properties to declare both the instance variables and the methods that access the instance variable.

Thus:

@interface MyClass:NSObject
@property(strong) NSMutableArray *myArray;
@end

@implementation MyClass
// the @property will automatically create an instance variable called _myArray,
// a getter method called -myArray and a setter called -setMyArray:

- init
{
    self = [super init];
    if (self) {
       _myArray = [NSMutableArray array]; // set the ivar directly in init
    }
    return self;
}

- (void)maybeAddThisThing:(Thing *)aThing
{
     if ([aThing isCool] && ![[self myArray] containsObject:aThing]) {
         [[self myArray] addObject:aThing];
     }
}

- (void)nukeFromOrbit
{
    [self setMyArray:[NSMutableArray array]];
    // or you could do [[self myArray] removeAllObjects];
}
share|improve this answer
    
ok, but then how would I make the array accessable in other functions if its only local to the one function (in this case bar)? –  user1624992 Jul 19 '13 at 1:33
    
    
However, I am using Xcode 3.1.4. It will not recognize the property... as a decleration of an instance variable. Also, I tried using the @synthesize myArray, and I tried synthesize myArray=_myArray and it still did not work –  user1624992 Jul 19 '13 at 21:35
1  
@user1624992 Xcode 3.1.4?! Why? You do realize that your app won't be accepted by Apple using such an old version. You really should update to Xcode 4.6 and take advantage of MANY new features of both iOS and Objective-C. –  rmaddy Jul 19 '13 at 21:39

The return of your NSMutableArray construction does not have an address known at compile time. You can only initialise dynamically inside method scope.

Static initialisation would be fine though: For example, NSString *myString = @"Hello String"; in global scope will compile just fine.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.