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 回答