1

質問のある 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]

2回目の繰り返し

arrayOfChoosenQuestions=[質問2 質問2]

3回目の繰り返し

arrayOfChoosenQuestions=[質問3 質問3 質問3]

ご協力ありがとうございました

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 に答える