cocos2d - 具有级别,重启级别和崩溃的NSMutableArray,下一级别工作正常

时间:2012-05-11 11:24:44

标签: ios crash cocos2d-iphone restart levels

我的nsmutablearray有关卡和两个按钮。下一级并再试一次。当用户触及下一级时,我设置objectAtIndex:indexCurrLevel + 1并且下一级加载没有问题。但是,如果用户再次尝试,我尝试将level设置为objectAtIndex:indexCurrLevel应用程序崩溃,已经添加了错误的子项。 这很疯狂,因为如果我手动设置再试一次。 objectAtIndex:5完美无缺,直到用户不在5级玩,因为app崩溃了。

对于与当前级别索引不同的索引,效果很好。 (objectAtIndex:index - works) 手动设置索引的原因与索引相同。

[self removeFromParentAndCleanup:YES];

    Levels *l = [levels2 objectAtIndex:index-1];
    Game *hl = [[Game alloc]initWithObstacles:[l staticO] :[l rotateO]:[l lvl]:[l level]:[l pendulumO]:self.levelsArray];
    [hl setLevels2:self.levels2];
    [hl setBasketY:[l basketY]];
    [hl setBasketX:[l basketX]];


    [l release];

    [[CCDirector sharedDirector] replaceScene:(CCScene*) hl];    
    [hl configureLevel];
    [hl release];

Eroor: 断言失败 - [Game addChild:z:tag:], ../libs/cocos2d/CCNode.m:388 2012-05-11 19:03:20.349游戏[932:10a03] *由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'child已添加。它不能再添加' * 首先抛出调用堆栈:

3 个答案:

答案 0 :(得分:0)

猜测数组边界问题,但如果没有代码示例或崩溃日志则无法验证。

答案 1 :(得分:0)

尝试删除语句[l release]。通常,您应该只使用以retaininitnew开头的方法释放您调用copy的对象或其他已获得的对象。数组levels2也将保留每个级别,将其保留为级别所有者可能是合适的。在Xcode中运行静态分析器来解决这些问题。

答案 2 :(得分:0)

阅读消息:您正在尝试addChild一个已经拥有父级的对象...即已经在代码库中的其他位置添加为CCNode后代的子级。 CCNode的第388行是NSAssert,不易破坏。暂时更改CCNode以获得可破坏的指令,如下所示:

if (nil==child) {
    CCLOG(@"%@<addChild> : have nil child. not adding.",self.class);
    return;
}
if (child.parent) {
    CCLOG(@"%@<addChild> : This child is already added somewhere. not adding.",self.class); // **** PUT BREAKPOINT HERE *****//
    return;
}

NSAssert( child != nil, @"Argument must be non-nil"); // was line 388
NSAssert( child.parent == nil, @"child already added. It can't be added again");

最后两行来自CCNode(在我的项目中)。如果你提到的错误发生,我会在指示的行中休息,重新运行,并查看堆栈跟踪。完成开发/测试周期后,这些事情对您很重要,请记住将cocos2d恢复到原始状态以进行此类临时模式。