user1419017
user1419017

Reputation: 33

Adding an Object to a NSMutableArray in a for loop I get the object duplicated in all positions

I have a sqlite database with questions and I want to write a function to get N random questions from it. I use a for loop with n iterations. For each iteration I get a question with a random ID which is not repeated. I copy the element of each column in a variable of an object of the class "question". Until here, everything is perfect. I have used NSLog to print the questions through all the function and all the process is right until I try to add the last object to a NSMutablearray. All the positions are overwritten. This is my code:

-(NSMutableArray*)getNQuestions:(int)n
{
    question *aQuestion=[[question alloc]init];

    NSMutableArray *arrayOfChoosenQuestions=[[NSMutableArray alloc]initWithCapacity:n];

    NSMutableIndexSet *choosenQuestionsIDs=[[NSMutableIndexSet alloc]init];

    FMResultSet *rs;
    int questionID;

    for (int i=0; i<n; i++) {
       questionID = (arc4random()%(NUMBER_OF_AVAILABLE_QUESTIONS-1))+1;
        while ([choosenQuestionsIDs containsIndex:questionID]) {
            questionID = (arc4random()%(NUMBER_OF_AVAILABLE_QUESTIONS-1))+1;
        }
        [choosenQuestionsIDs addIndex:questionID];

        rs = [database executeQueryWithFormat:@"SELECT * FROM questions WHERE Questions.ID=%d", questionID];

        if ([rs next] ) {
            aQuestion.statement=[rs stringForColumn:@"Question"];
            aQuestion.rightAnswer=[rs stringForColumn:@"Right_Answer"];
            aQuestion.wrongAnswer1=[rs stringForColumn:@"Wrong_Answer_1"];
            aQuestion.wrongAnswer2=[rs stringForColumn:@"Wrong_Answer_2"];
            aQuestion.image=[rs stringForColumn:@"image"];
        }
        [arrayOfChoosenQuestions addObject:aQuestion];
    }
    return arrayOfChoosenQuestions;
}

This is an example of what happen

1rst iteration:

arrayOfChoosenQuestions=[question1]

2nd iteration

arrayOfChoosenQuestions=[question2 question2]

3rd iteration

arrayOfChoosenQuestions=[question3 question3 question3]

Thank You for your help

Upvotes: 1

Views: 386

Answers (2)

Dave DeLong
Dave DeLong

Reputation: 243156

In addition to nhahtdh said, your method is overly complex. It could probably be simplified to this:

-(NSMutableArray*)fetchNQuestions:(int)n {
    NSMutableArray *questions = [NSMutableArray array];

    FMResultSet *rs = [database executeQueryWithFormat:@"SELECT * FROM questions ORDER BY RANDOM LIMIT %d", n];
    while ([rs next]) {
      Question *q = [[Question alloc] init];

      [q setStatement:[rs stringForColumn:@"Question"]];
      ...
      [questions addObject:q];

      // if you're not using ARC:
      [q release];
    }
    return questions;
}

Upvotes: 2

nhahtdh
nhahtdh

Reputation: 56819

You are re-using the same question object (which is aQuestion) over and over again, so you are actually modifying and inserting the same underlying object into the array.

Basically, in your current code, you are referring to the same block of memory when you are reading from/writing to aQuestion. All modification will go to the same position in memory. As you can see, the change "propagate" to other objects, since they are actually the same memory block referred to by the pointer in aQuestion.

For each loop, you have to create a new question object to accommodate new data.

Upvotes: 3

Related Questions