Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios SIGSEGV调试:cocos2d iphone中定义的update()方法在哪里?_Ios_Objective C_Cocos2d Iphone - Fatal编程技术网

Ios SIGSEGV调试:cocos2d iphone中定义的update()方法在哪里?

Ios SIGSEGV调试:cocos2d iphone中定义的update()方法在哪里?,ios,objective-c,cocos2d-iphone,Ios,Objective C,Cocos2d Iphone,我正试图解决cocos2diphone1.0.1中的SIGSEGV信号错误。我必须指出,尽管我努力了几个小时,但实际上我无法复制这次崩溃。我只知道这是因为测试人员 我收集了尽可能多的信息。首先,这里是TestFlight回溯: 太好了。让我们看看 CCScheduler 代码>蜱虫>代码>方法。它相当大,因此我这里只有发生错误的代码块(在问题的底部,您可以看到完整的方法): 好。所以我们找到了罪犯的线索 让我们看看,impMethod是类型TICK\u IMP,定义为 typedef void

我正试图解决
cocos2diphone1.0.1
中的
SIGSEGV
信号错误。我必须指出,尽管我努力了几个小时,但实际上我无法复制这次崩溃。我只知道这是因为测试人员

我收集了尽可能多的信息。首先,这里是TestFlight回溯:

太好了。让我们看看<代码> CCScheduler <代码>代码>蜱虫>代码>方法。它相当大,因此我这里只有发生错误的代码块(在问题的底部,您可以看到完整的方法):

好。所以我们找到了罪犯的线索

让我们看看,
impMethod
是类型
TICK\u IMP
,定义为

typedef void (*TICK_IMP)(id, SEL, ccTime);
嗯。
impMethod(elt->currentTimer,updateSelector,dt)
本身没有任何问题

仔细看,我最好的猜测是
elt->currentTimer
可能有问题

起初,我认为如果
elt
NULL
指针,调用
elt->currentTimer
可能会导致分段错误。然而,我最近被告知,即使
elt
NULL
,向它发送消息也不会导致
SIGSEGV
错误

我已经确认了这一点,因为我最终用
if(elt!=NULL)
包装了该方法,但它仍然存在,所以问题一定是其他原因

在没有线索的情况下,我突然想到,这段代码并不能导致错误。它一定是我代码中其他地方的模糊信息

让我看看。如果我在罪魁祸首行之前执行
NSLog
,如下所示:

NSLog(@"[%@ %@]" , [elt->target class],NSStringFromSelector(updateSelector));
我可以告诉什么是最后一个被更新的预定对象,甚至可以得到相应的方法

在使我的测试人员再次崩溃后,我最终得到了以下结果:

[游戏更新]

好极了<代码>游戏是游戏的主要场景,因此问题似乎与此类场景有关

但是等等。对于我的场景,没有这样的方法
update
。我从来没有实现过这样的事情

然后我想既然
Game
CCScene
对象,也许
CCScene
确实有这样的方法。但我看到了它的实现,却没有。但是等等,
CCScene
CCNode
的子类!让我们来看看<代码> CCNode <代码> .< 。。。
CCNode
中也没有
update
方法

我确实发现了一些关于
CCNode
的奇怪之处:

-(void) scheduleUpdate;
显然,它负责安排每帧调用一次
update
方法,而且确实如此。下面是这类程序的一个特定行:

[target methodForSelector:updateSelector];
其中
目标
应该是
游戏
更新选择器
@selector(更新:)

但是,这没有任何意义:在哪里应该实现这个
更新
方法?我在
CCNode
的任何地方都找不到它。因此,它怎么可能安排这种方法呢

通常,我会说这就是导致错误的原因——我们正在安排一个未实现的方法,从而导致
SIGSEGV
错误。然而,这很奇怪,因为如果这是真的,那么它应该一直崩溃,但事实并非如此

这就是我试着调试这个错误所得到的结果。我错过了什么

我知道你不能告诉我问题出在哪里,但我相信我得到了一条重要的线索,你可以解释一下:在cocos2d中
update
在哪里实现


这是
CCScheduler
勾选
方法的完整代码,以防万一:

-(void) tick: (ccTime) dt {
    updateHashLocked = YES;

    if( timeScale_ != 1.0f )
        dt *= timeScale_;

        // Iterate all over the Updates selectors
        tListEntry *entry, *tmp;

    // updates with priority < 0
    DL_FOREACH_SAFE( updatesNeg, entry, tmp ) {
        if( ! entry->paused && !entry->markedForDeletion )
            entry->impMethod( entry->target, updateSelector, dt );
    }

    // updates with priority == 0
    DL_FOREACH_SAFE( updates0, entry, tmp ) {
        if( ! entry->paused && !entry->markedForDeletion )
        {
            entry->impMethod( entry->target, updateSelector, dt );
        }
    }

    // updates with priority > 0
    DL_FOREACH_SAFE( updatesPos, entry, tmp ) {
        if( ! entry->paused  && !entry->markedForDeletion )
            entry->impMethod( entry->target, updateSelector, dt );
    }

    // Iterate all over the  custome selectors
    for(tHashSelectorEntry *elt=hashForSelectors; elt != NULL; ) {

        currentTarget = elt;
        currentTargetSalvaged = NO;

        if( ! currentTarget->paused ) {

            // The 'timers' ccArray may change while inside this loop.
            for( elt->timerIndex = 0; elt->timerIndex < elt->timers->num; elt->timerIndex++) {
                elt->currentTimer = elt->timers->arr[elt->timerIndex];
                elt->currentTimerSalvaged = NO;

                impMethod( elt->currentTimer, updateSelector, dt);

                if( elt->currentTimerSalvaged ) {
                    // The currentTimer told the remove itself. To prevent the timer from
                    // accidentally deallocating itself before finishing its step, we retained
                    // it. Now that step is done, it's safe to release it.
                    [elt->currentTimer release];
                }

                elt->currentTimer = nil;
            }
        }

        if (elt != NULL) {
            // elt, at this moment, is still valid
            // so it is safe to ask this here (issue #490)
            elt = elt->hh.next;

            // only delete currentTarget if no actions were scheduled during the cycle (issue #481)
            if( currentTargetSalvaged && currentTarget->timers->num == 0 )
                [self removeHashElement:currentTarget];
        }
    }

    // delete all updates that are morked for deletion
    // updates with priority < 0
    DL_FOREACH_SAFE( updatesNeg, entry, tmp ) {
        if(entry->markedForDeletion )
        {
            [self removeUpdateFromHash:entry];
        }
    }

    // updates with priority == 0
    DL_FOREACH_SAFE( updates0, entry, tmp ) {
        if(entry->markedForDeletion )
        {
            [self removeUpdateFromHash:entry];
        }
    }

    // updates with priority > 0
    DL_FOREACH_SAFE( updatesPos, entry, tmp ) {
        if(entry->markedForDeletion )
        {
            [self removeUpdateFromHash:entry];
        }
    }

    updateHashLocked = NO;
    currentTarget = nil;
}
-(无效)勾选:(ccTime)dt{
updatehashlock=YES;
如果(时间刻度=1.0f)
dt*=时间刻度;
//迭代所有更新选择器
tListEntry*条目,*tmp;
//优先级<0的更新
DL_FOREACH_SAFE(updatesNeg、entry、tmp){
如果(!entry->paused&!entry->markedForDeletion)
条目->导入方法(条目->目标,更新选择器,dt);
}
//优先级==0的更新
DL_FOREACH_SAFE(更新0、条目、tmp){
如果(!entry->paused&!entry->markedForDeletion)
{
条目->导入方法(条目->目标,更新选择器,dt);
}
}
//优先级>0的更新
DL_FOREACH_SAFE(更新操作系统、条目、tmp){
如果(!entry->paused&!entry->markedForDeletion)
条目->导入方法(条目->目标,更新选择器,dt);
}
//迭代所有自定义选择器
for(tHashSelectorEntry*elt=hashForSelectors;elt!=NULL;){
当前目标=elt;
currentTargetSalvaged=否;
如果(!currentTarget->暂停){
//“定时器”阵列在此循环内可能会发生变化。
对于(elt->timerIndex=0;elt->timerIndextimers->num;elt->timerIndex++){
elt->currentTimer=elt->timers->arr[elt->timerIndex];
elt->CurrentTimerSalvage=否;
impMethod(elt->currentTimer,updateSelector,dt);
如果(elt->CurrentTimerSalvated){
//currentTimer通知移除本身。以防止计时器
//在完成步骤之前意外地释放了自己,我们保留了
//现在,这一步已经完成,可以安全地释放它了。
[elt->currentTimer release];
}
elt->currentTimer=nil;
}
}
如果(elt!=NULL){
//目前,英语教学仍然有效
//因此,在这里问这个问题是安全的(第490期)
elt=elt->hh.next;
//仅在循环期间未计划任何操作时删除currentTarget(问题#481)
我
[target methodForSelector:updateSelector];
-(void) tick: (ccTime) dt {
    updateHashLocked = YES;

    if( timeScale_ != 1.0f )
        dt *= timeScale_;

        // Iterate all over the Updates selectors
        tListEntry *entry, *tmp;

    // updates with priority < 0
    DL_FOREACH_SAFE( updatesNeg, entry, tmp ) {
        if( ! entry->paused && !entry->markedForDeletion )
            entry->impMethod( entry->target, updateSelector, dt );
    }

    // updates with priority == 0
    DL_FOREACH_SAFE( updates0, entry, tmp ) {
        if( ! entry->paused && !entry->markedForDeletion )
        {
            entry->impMethod( entry->target, updateSelector, dt );
        }
    }

    // updates with priority > 0
    DL_FOREACH_SAFE( updatesPos, entry, tmp ) {
        if( ! entry->paused  && !entry->markedForDeletion )
            entry->impMethod( entry->target, updateSelector, dt );
    }

    // Iterate all over the  custome selectors
    for(tHashSelectorEntry *elt=hashForSelectors; elt != NULL; ) {

        currentTarget = elt;
        currentTargetSalvaged = NO;

        if( ! currentTarget->paused ) {

            // The 'timers' ccArray may change while inside this loop.
            for( elt->timerIndex = 0; elt->timerIndex < elt->timers->num; elt->timerIndex++) {
                elt->currentTimer = elt->timers->arr[elt->timerIndex];
                elt->currentTimerSalvaged = NO;

                impMethod( elt->currentTimer, updateSelector, dt);

                if( elt->currentTimerSalvaged ) {
                    // The currentTimer told the remove itself. To prevent the timer from
                    // accidentally deallocating itself before finishing its step, we retained
                    // it. Now that step is done, it's safe to release it.
                    [elt->currentTimer release];
                }

                elt->currentTimer = nil;
            }
        }

        if (elt != NULL) {
            // elt, at this moment, is still valid
            // so it is safe to ask this here (issue #490)
            elt = elt->hh.next;

            // only delete currentTarget if no actions were scheduled during the cycle (issue #481)
            if( currentTargetSalvaged && currentTarget->timers->num == 0 )
                [self removeHashElement:currentTarget];
        }
    }

    // delete all updates that are morked for deletion
    // updates with priority < 0
    DL_FOREACH_SAFE( updatesNeg, entry, tmp ) {
        if(entry->markedForDeletion )
        {
            [self removeUpdateFromHash:entry];
        }
    }

    // updates with priority == 0
    DL_FOREACH_SAFE( updates0, entry, tmp ) {
        if(entry->markedForDeletion )
        {
            [self removeUpdateFromHash:entry];
        }
    }

    // updates with priority > 0
    DL_FOREACH_SAFE( updatesPos, entry, tmp ) {
        if(entry->markedForDeletion )
        {
            [self removeUpdateFromHash:entry];
        }
    }

    updateHashLocked = NO;
    currentTarget = nil;
}