在for循环中将对象添加到NSMutableArray我得到的对象在所有位置都是重复的

时间:2012-05-26 13:11:39

标签: objective-c nsmutablearray

我有一个带问题的sqlite数据库,我想编写一个函数来从中获取N个随机问题。我使用一个带有n次迭代的for循环。对于每次迭代,我得到一个带有随机ID的问题,不再重复。我将每个列的元素复制到“问题”类的对象的变量中。在这里,一切都很完美。我已经使用NSLog通过所有函数打印问题,所有过程都是正确的,直到我尝试将最后一个对象添加到NSMutablearray。所有职位都被覆盖。 这是我的代码:

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

这是发生的事情的一个例子

第一次迭代:

arrayOfChoosenQuestions = [问题1]

第二次迭代

arrayOfChoosenQuestions = [question2 question2]

第3次迭代

arrayOfChoosenQuestions = [question3 question3 question3]

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

您反复使用相同的question对象(aQuestion),因此您实际上正在修改相同的基础对象并将其插入到阵列。

基本上,在您当前的代码中,当您阅读/写入aQuestion时,您指的是相同的内存块。所有修改都将转到内存中的相同位置。如您所见,更改“传播”到其他对象,因为它们实际上是aQuestion中指针引用的相同内存块。

对于每个循环,您必须创建一个新的question对象以容纳新数据。

答案 1 :(得分:2)

除了nhahtdh说,你的方法过于复杂。它可能简化为:

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