// Interate all script functions
for (tHashScriptFuncEntry **elt = m_pHashForScriptFunctions; elt != NULL; )
{
if
{
elt~~>timer~~>update;
}
elt = elt~~>hh.next;
}
}
above is part of the code of the cocos2d-1.0.1-x-0.10.0 version
the problem is If We call unscheduleScriptFunc function in the registed func, the property elt will be NULL after elt~~>timer~~>update, then elt = elt~~>hh.next; will cause a crash.
here is my test code in lua:
local count = 1
function cb
count = count + 1
if count == 10 then
cocos2d.CCScheduler:sharedScheduler:unscheduleScriptFunc
end
end
cocos2d.CCScheduler:sharedScheduler:scheduleScriptFunc
the way to solve this problem is quite simple, below is my solution
tHashScriptFuncEntry**eltTemp = (tHashScriptFuncEntry *)elt~~>hh.next;
if
{
elt~~>timer->update(dt);
}
Hi Minggo,
I sure that I have the correct solution now, which is quite similar to the original unscheduleSelector.
Below is the detail:
add currentTimerSalvaged to tHashScriptFuncEntry as a flag, will delete the entry if it is true
typedef struct _hashScriptFuncEntry
{
CCTimer timer;
bool paused;
bool currentTimerSalvaged;
const charfuncName;
UT_hash_handle hh;
} tHashScriptFuncEntry;
add function void removeHashScriptFuncElement(struct _hashScriptFuncEntry pElement);
void CCScheduler::removeHashScriptFuncElement
{
if
{
pElement~~>timer~~>release;
pElement~~>timer = NULL;
HASH_DEL;
free;
}
}
3.Modify function unscheduleScriptFunc. do not delete entry in here, only mark it
if
{
pElement~~>currentTimerSalvaged = true;
}
4.modify function tick.
// Interate all script functions
for
{
tHashScriptFuncEntrypNextElement = (tHashScriptFuncEntry *)elt~~>hh.next;
if
{
elt~~>timer->update(dt);
if( elt->currentTimerSalvaged )
{
removeHashScriptFuncElement(elt);
}
}