0

情况:
在 CCCallFunc 之后不久,我遇到了一些神秘的崩溃。简而言之,我们有一个按钮。该按钮有一个标签,以便以后识别它。当按钮被按下时,我们运行一些动作来动画它,当动画完成时,我们 CCCallFunc 另一个方法来转换到另一个场景。我们在 CCCallFunc 之后不久就崩溃了。来源和错误如下。

崩溃点(在 cocos2d 源中):

// From CCActionInstant.m of cocos2d
-(void) execute
{
    /*** EXC_BAD_ACCESS on line 287 of CCActionInstant.m ***/
    [targetCallback_ performSelector:selector_];
}
@end

线程 1 的快照:
线程 1 堆栈

我的代码:
下面是取自 MenuLayer.m 的一些源代码(一个显示按钮的简单菜单)。

// from MenuLayer.m
// …

@implementation MenuLayer

-(id) init{

    if((self=[super init])) {

    /****** Create The Play Button (As a CCMenu) ********/
        CCSprite *playSprite = [CCSprite spriteWithFile:@"playbutton.png"];

        CCMenuItemSprite *playItem = [CCMenuItemSprite itemFromNormalSprite:playSprite selectedSprite:nil target:self selector:@selector(animateButton:)];
        playItem.tag = 3001;
        playItem.position = ccp(160.0f, 240.0f);

        CCMenu *menu = [CCMenu menuWithItems:playItem, nil];
        menu.position = ccp(0.0f, 0.0f);
        [self addChild:menu z:0];

    }
}

// ...

- (void)animateButton:(id)sender{

    /*** Run an animation on the button and then call a function ***/
    id a1 = [CCScaleTo actionWithDuration:0.05 scale:1.25];
    id a2 = [CCScaleTo actionWithDuration:0.05 scale:1.0];
    id aDone = [CCCallFunc actionWithTarget:self selector:@selector(animationDone:)];
    [sender runAction:[CCSequence actions:a1,a2,aDone, nil]];

}
- (void)animationDone:(id)sender{

    /*** Identify button by tag ***/
    /*** Call appropriate method based on tag ***/
    if([(CCNode*)sender tag] == 3001){

    /*** crashes around here (see CCActionInstant.m) ***/
        [self goGame:sender];
    }
}

-(void)goGame:(id)sender{

        /*** Switch to another scene ***/
    CCScene *newScene = [CCScene node];
    [newScene addChild:[StageSelectLayer node]];

        if ([[CCDirector sharedDirector] runningScene]) {
            [[CCDirector sharedDirector] replaceScene:newScene]];
        }else {
            [[CCDirector sharedDirector] runWithScene:newScene];
        }
}
4

2 回答 2

2

只是一种预感。除了检查内存泄漏,尝试安排一个 0 秒间隔的选择器,而不是直接发送 goGame 消息。我怀疑导演的 replaceScene 会清理场景和与之相关的所有对象。这反过来可能会使 CCCallFunc 操作处于未定义状态。虽然通常它工作正常 - 也就是说,这只是粗略的,内存 - 分别是对象生命周期管理方面的另一个迹象。

顺便说一句,如果您至少支持 iOS 4,请使用 CCCallBlock 而不是 CCCallFunc。这样更安全、更清洁。

于 2012-05-21T21:19:09.053 回答
2

使用 CCCallFuncN 代替 CCCallFun。

CCCallFuncN 将节点作为参数传递,CCCallFun 的问题是您丢失了节点的引用。

我用 CCCallFuncN 测试你的代码并且工作正常。

于 2012-05-22T19:22:12.823 回答