Objective-C循环问题

时间:2011-08-18 19:30:11

标签: iphone objective-c ios for-loop

我有两个方法,在testMethod中调用generateRandomCard方法,其中有一个运行100次的for循环。这样它的工作完美,但是如果我将for循环限制设置为1000或任何其他大于100的数字,它就会崩溃。你能看出什么问题吗?

- (void)testMethod {

    Globals *myGlobals = [Globals sharedInstance];
    int rankOfFirst = 0;
    int rankOfSecond = 0;
    int playerOneWin = 0;
    int playerTwoWin = 0;
    int ties = 0;
    float firstPercent = 0;
    float secondPercent = 0;
    float tiePercent = 0;
    FiveEval *evaluator = [FiveEval theEvaluator];

    for (int i = 0; i < 100; i++) {
        short fPF = [self generateRandomCard];
        short fPS = [self generateRandomCard];
        short sPF = [self generateRandomCard];
        short sPS = [self generateRandomCard];
        short fFlop = [self generateRandomCard];
        short sFlop = [self generateRandomCard];
        short tFlop = [self generateRandomCard];
        short tur = [self generateRandomCard];
        short riv = [self generateRandomCard];

        rankOfFirst = [evaluator getRankOfSeven:fFlop 
                                               :sFlop 
                                               :tFlop
                                               :tur 
                                               :riv 
                                               :fPF 
                                               :fPS];

        rankOfSecond = [evaluator getRankOfSeven:fFlop 
                                             :sFlop 
                                             :tFlop 
                                             :tur 
                                             :riv 
                                             :sPF 
                                             :sPS];

        if (rankOfFirst > rankOfSecond) {
            playerOneWin++;
        } else if (rankOfSecond > rankOfFirst) {
            playerTwoWin++;
        } else {
            ties++;
        }

        [myGlobals.alreadyPickedCards removeAllObjects];
    }

    firstPercent = ((float)playerOneWin/(float)10000)*100;
    secondPercent = ((float)playerTwoWin/(float)10000)*100;
    tiePercent = ((float)ties/(float)10000)*100;

    NSLog(@"First Player Equity: %f", firstPercent);
    NSLog(@"Second Player Equity: %f", secondPercent);
    NSLog(@"Tie Equity: %f", tiePercent);
}


- (short)generateRandomCard {

    Globals *myGlobals = [Globals sharedInstance];
    short i = arc4random()%51;
    for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
        if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
            [self generateRandomCard];
        }
    }
    [myGlobals.alreadyPickedCards addObject:[NSNumber numberWithShort:i]];
    return i;
}

3 个答案:

答案 0 :(得分:3)

-generateRandomCard的递归调用中,您可能overflowing your stack。如果你生成一张已经被挑选过的卡片,你会递归地调用自己(并忽略结果,这是一个不同的错误)。所以,如果你的随机数字流给你一个不幸的序列,让你已经选择了返回的牌,那么你将无限地递归,直到堆栈溢出。

更改您的卡片选择算法,以便不使用具有无限循环/递归潜力的rejection sampling,而是使用具有有界运行时间的算法,例如Fisher-Yates shuffle

答案 1 :(得分:1)

不确定这是否会以任何方式导致崩溃 - 这可能是无关的。但是,当在alreadyPickedCards数组中找到卡时,看起来你在递归调用generateRandomCard的方式上有一个错误。而不是

[self generateRandomCard];

我认为你应该

return [self generateRandomCard];

答案 2 :(得分:0)

你有-testMethod: [myGlobals.alreadyPickedCards removeAllObjects];

和in -generateRandomCard你有:

for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
    if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
        [self generateRandomCard];
    }
}

我不能肯定地下注,但这看起来像是在1循环中删除AllObjects并在另一个循环中访问out of bound索引的情况。

如果您想使用数组播放,我建议您复制数组并从复制的数组中删除项目。