Random 目标-C EXC_坏访问

Random 目标-C EXC_坏访问,random,nsmutablearray,exc-bad-access,Random,Nsmutablearray,Exc Bad Access,好的,所以我最近决定尝试自学Objective-C(我对iPhone开发很感兴趣),但是我以前从未使用过C或它的任何衍生物,因此我遇到了一些问题。 我决定首先编写一个非常基本的卡片应用程序,创建一副卡片,洗牌,然后使用UIButtons在屏幕上显示这些卡片,但是我的洗牌算法有问题。每次它被调用时,我都会收到一个EXC_BAD_访问错误,我知道这意味着我的代码有严重的错误,但我就是不知道它是什么 - (void) randomize { NSMutableArray *tmpDeck =

好的,所以我最近决定尝试自学Objective-C(我对iPhone开发很感兴趣),但是我以前从未使用过C或它的任何衍生物,因此我遇到了一些问题。 我决定首先编写一个非常基本的卡片应用程序,创建一副卡片,洗牌,然后使用UIButtons在屏幕上显示这些卡片,但是我的洗牌算法有问题。每次它被调用时,我都会收到一个EXC_BAD_访问错误,我知道这意味着我的代码有严重的错误,但我就是不知道它是什么

- (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的指针,其中包含未缓冲的card对象组,而_hasBeenRandomized是一个布尔值(显然),用于跟踪组是否已随机

我曾尝试使用调试器来确定这里到底发生了什么,但我甚至无法在程序崩溃的情况下使用该方法。这让我相信问题必须从第一行开始,但这只是一个NSMutableArray的简单创建,所以我不知道怎么会这样。正在从viewDidLoad中调用此方法。这是当前viewDidLoad方法的全部内容

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

任何和所有的帮助都将不胜感激。如果答案非常明显,很抱歉。

这是因为您试图插入到一个尚不存在的索引中。您需要在阵列中按卡的数量初始化阵列。或者使用NSMutableDictionary,插入索引为键的对象

另外,在数组上调用initWithCapacity也不能解决这一问题,因为这只是给出了大小的“提示”。您需要数组的count属性实际至少与您尝试插入的索引一样大。如果您想创建一个数组,那么首先需要在每个索引中填充一些内容。您可以用新的数组文字格式定义它,或者使用一个for循环来循环您需要的次数(您的最大索引),并在它的位置插入一个虚拟对象

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

如果仍然出现相同的错误,请在调试器中设置断点,并检查随机数和数组计数。如果随机数大于数组计数,则会出现此错误。

我对此有些困惑。我知道您必须用Java等语言初始化数组的大小,但我创建了原始的NSMutableArray,它按顺序存放卡片,而没有指定需要的索引数量。因此,我假设您不需要在Objective-C中指定数组的大小。您知道为什么它在第一种情况下有效,但在本例中无效吗?这与原始数组中的卡是按顺序插入的,而不是随机索引插入的这一事实有什么关系吗?第一个数组是在甲板对象初始化期间创建的。谢谢。当然,您可以指定数组的大小。但这只是提示编译器需要多少“内存”,并不意味着可变数组不会扩展。如果使用对象初始化数组,或者按顺序推送它们,那么数组将继续添加一个索引。但是,您不能只访问尚未创建的索引。我会把我个人在这种情况下会做的事情写在编辑中给你。请注意,您还可以一次向NSMutableArray添加多个对象,甚至现在可以使用文字来声明它们。请注意,我要这样做需要对整个数组进行额外的迭代,因此我们必须权衡两个缺点,我现在不会这么做。无论如何,我希望这会有所帮助,苹果的开发者文档是这方面的一个很好的资源。阅读一些有关NSMutable数组/字典的内容。顺便说一下,如果您选择NSDictionary路线,则需要将索引转换为键的对象。你可以做这样的数字文字@(随机)。Johnrechd,非常感谢你的帮助,但不幸的是,我仍然得到相同的EXC\u BAD\u访问权限。我完全用了你的密码。它运行一个for循环,用@“dummy”填充数组,然后,它检查@“dummy”,而不是检查nil。不幸的是,我仍然在运行时出错。
[tmpDeck replaceObjectAtIndex:random withObject:tmp];