情况:
在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的快照:
我的代码:
以下是从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];
}
}
答案 0 :(得分:2)
只是预感。除了检查内存泄漏之外,尝试以0秒的间隔安排选择器,而不是直接发送goGame消息。我怀疑导演的replaceScene会导致场景的清理以及与之相关的所有对象。这反过来可能使CCCallFunc操作处于未定义状态。虽然通常它工作正常 - 也就是说这只是关于粗略,记忆 - 对象 - 生命周期 - 管理方面的另一个指示。
顺便说一句,如果您至少支持iOS 4,请使用CCCallBlock而不是CCCallFunc。那更安全,更清洁。
答案 1 :(得分:2)
使用CCCallFuncN而不是CCCallFun。
CCCallFuncN将Node作为参数传递,CCCallFun的问题在于你正在丢失节点的引用。
我用CCCallFuncN测试你的代码并且工作正常。