2

わかりましたので、最近、Objective-C を独学で学ぼうと決心しました (私は iPhone 開発に興味があります) が、C やその派生物をこれまで使用したことがないため、いくつかの問題に遭遇しています。カードのデッキを作成し、デッキをシャッフルし、UIButtons を使用して画面にカードを表示する非常に基本的なカード アプリケーションを作成することから始めることにしましたが、シャッフル アルゴリズムに問題があります。呼び出されるたびに、EXC_BAD_ACCESS エラーが発生します。これは、コードに致命的な問題があることを意味しますが、それが何であるかを理解することはできません。

- (void) randomize {
    NSMutableArray *tmpDeck = [[NSMutableArray alloc] init];
    for(Card *tmp in _cards) {
        BOOL didInsert = NO;
        while(!didInsert) {
            NSUInteger random = arc4random_uniform(54);
            if([[tmpDeck objectAtIndex:random] isEqual:nil]) {
                [tmpDeck insertObject:tmp atIndex:random];
                didInsert = YES;
            }
        }
    }
    _cards = tmpDeck;
    _hasBeenRandomized = YES;
}

_cards は、シャッフルされていないカード オブジェクトのデッキを含む NSMutableArray へのポインターであり、_hasBeenRandomized は、デッキがランダム化されているかどうかを追跡する (明らかに) ブール値です。

ここで何が起こっているのかを正確に把握するためにデバッガーを使用しようとしましたが、プログラムがクラッシュせずにメソッドにステップインすることさえできません。これにより、問題は最初の行から発生する必要があると思われますが、これは NSMutableArray の単純な作成にすぎないため、どうしてそうなるのかわかりません。このメソッドは、viewDidLoad 内から呼び出されています。これは現在の viewDidLoad メソッド全体です。

- (void)viewDidLoad
{
    [super viewDidLoad];
    _deck = [[Deck alloc] init];
    [_deck randomize];
}

ありとあらゆる助けをいただければ幸いです。答えが明らかである場合は申し訳ありません。

4

1 に答える 1

1

これは、まだ存在しないインデックスに挿入しようとしているためです。カードに必要な数の配列内の場所で配列を初期化する必要があります。それか、NSMutableDictionary を使用して、インデックスをキーとしてオブジェクトを挿入するだけです。

別のメモを追加するには、配列で initWithCapacity を呼び出しても、サイズの「ヒント」が得られるだけなので、これは解決されません。実際には、挿入しようとしているインデックスと少なくとも同じ大きさの配列の count プロパティが必要です。配列を作成したい場合は、最初に各インデックスに何かを設定する必要があります。これを新しい配列リテラル形式で定義するか、必要な回数 (最大インデックス) ループする for ループを使用して、その場所にダミー オブジェクトを挿入することができます。

for (int i=0; i< _cards.count; ++i) 
{
    [tmpDeck insertObject:@"dummy" atIndex:i];
}

次に、置換前に「nil」をチェックする代わりに、挿入したダミー オブジェクトと等しいかどうかをチェックします。これにより、これらのインデックスのいずれかに挿入できる配列が得られます。個人的には、おそらく NSMutableDictionary に保存するでしょう。しかし、他の目的のために配列でそれが必要な場合は、これがその方法です。

また、オブジェクトを挿入するのではなく、必ず置換する必要があります。そうしないと、インデックスを追加し続けることになります。

[tmpDeck replaceObjectAtIndex:random withObject:tmp];

それでも同じエラーが発生する場合は、デバッガーにブレークポイントを設定し、乱数と配列のカウントを確認してください。乱数が配列の数よりも大きい場合、このエラーが発生します。

于 2013-02-28T03:39:13.530 に答える