1

我有一个带有问题的 sqlite 数据库,我想编写一个函数来从中获取 N 个随机问题。我使用带有 n 次迭代的 for 循环。对于每次迭代,我都会收到一个带有随机 ID 的问题,该 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=[问题 2 问题 2]

第三次迭代

arrayOfChoosenQuestions=[question3 question3 question3]

感谢您的帮助

4

2 回答 2

3

您一遍又一遍地重复使用相同的question对象(即),因此您实际上是在修改相同的底层对象并将其插入到数组中。aQuestion

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

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

于 2012-05-26T13:20:56.660 回答
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;
}
于 2012-05-26T14:14:57.973 回答