5

I'm trying to create an array (States) of arrays (Cities). Whenever I try to add an item to my City array I get this error:

'NSInvalidArgumentException', reason: '*** +[NSMutableArray addObject:]: unrecognized selector sent to class 0x303097a0

My code is as follows. The line it errors on is

 [currentCities addObject:city];

I'm sure I've got some Memory Management problem as I still don't understand it all that well. Was hoping someone could explain my mistake to me.

if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
        // We need to keep track of the state we are on
        NSString *state = @"none";
        NSMutableArray *currentCities = [NSMutableArray alloc];

        // We "step" through the results - once for each row
        while (sqlite3_step(statement) == SQLITE_ROW){
            // The second parameter indicates the column index into the result set.
            int primaryKey = sqlite3_column_int(statement, 0);
            City *city = [[City alloc] initWithPrimaryKey:primaryKey database:db];

            if (![state isEqualToString:city.state])
            {
                // We switched states
                state = [[NSString alloc] initWithString:city.state]; 

                // Add the old array to the states array
                [self.states addObject:currentCities];

                // set up a new cities array
                currentCities = [NSMutableArray init];
            }

            [currentCities addObject:city];
            [city release];
        }
    }

3 Answers 3

9

The lines:

// set up a new cities array
currentCities = [NSMutableArray init];

Should read:

// set up a new cities array
[currentCities init];

which should hopefully fix your problem. Instead of initializing your array, you're sending an init message to a class object, which doesn't do anything. Afterwards, you're currentCities pointer is still not initialized.

Even better would be to remove that line and change the 4th line such that you allocate and initialize all in one step:

NSMutableArray *currentCities = [[NSMutableArray alloc] init];
Sign up to request clarification or add additional context in comments.

3 Comments

If you do separate initialization (which you shouldn't, but if you do), it needs to read currentCities = [currentCities init]. NSArray initializers never return the receiver, and no class's initializer is guaranteed to do so.
The reason I have the [currentCities init]; line is because it will need to initialize a new instance when we switch to the next state. Changing that line did fix this issue but raised another issue, however adding the second step you mentioned ([[NSMutableArray alloc] init]) fixed that issue. Thank you.
If you initialize a new instance, you should be allocating a new instance as well.
3

You need to call some sort of initializer on NSMutableArray, don't you? initWithCapacity, or something like that? Not sure what you get if you leave it off.

** Just tested it. Make it [[NSMutableArray alloc] init] and you will be fine.

Comments

1

It was initialization problem for me.

Had to change from

NSMutableArray *myArray  = [NSMutableArray mutableCopy]; // not initialized.  don't know why this even compiles
[myArray addObject:someObject];  // crashed

to

NSMutableArray *myArray  = [NSMutableArray new]; // initialized!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.