1

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

2
  • This can't be right: [arrayOfChoosenQuestions addIndex:questionID];. Commented May 26, 2012 at 13:21
  • sorry, I have translated the code from my language and I made this mistake Commented May 26, 2012 at 13:44

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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;
}

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.