请看清楚程序在哪里挂的,fixedPriorityListeners访问越界
一个健壮的引擎,不应该出现这种问题的
嗯,看清楚了,我联系了2dx的版主,给你移动到那边了哈。
先给EventListener加个Tag属性。排查下是哪个listener被释放掉。是以什么样的方式被释放掉(手动移除?节点被移除?移除的时机?),我这边是需要进行重现,才能修改引擎的。感谢您的配合。
BUG不是每次重现,下次出现的时候我再详细跟一下看看
现在我能重现这个BUG,但是代码不方便提供
我能确认是
1、这个BUG是在事件响应过程中再次dispatcher了同一个事件的情况下发生的
2、监听者数组是在EventDispatcher::updateListeners(Event* event)中被修改的,然后结合1的情况就会造成BUG
终于写出重现的代码了:
#include "cocos2d.h"
class BugUnit : public cocos2d::Ref
{
public:
virtual ~BugUnit();
CREATE_FUNC(BugUnit);
virtual bool init();
protected:
cocos2d::EventListenerCustom* _listener;
void eventCallback(cocos2d::EventCustom *event);
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BugUnit.cpp ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BugUnit::~BugUnit()
{
if (_listener != nullptr)
{
cocos2d::Director::getInstance()->getEventDispatcher()->removeEventListener(_listener);
CC_SAFE_RELEASE_NULL(_listener);
}
}
bool BugUnit::init()
{
do
{
_listener = EventListenerCustom::create("remove_child", CC_CALLBACK_1(BugUnit::eventCallback, this));
CC_BREAK_IF(_listener == nullptr);
_listener->retain();
cocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_listener, 1);
return true;
}while (0);
return false;
}
void BugUnit::eventCallback(cocos2d::EventCustom *event)
{
if (event->getEventName() == "remove_child")
{
if (_listener != nullptr)
{
cocos2d::Director::getInstance()->getEventDispatcher()->removeEventListener(_listener);
CC_SAFE_RELEASE_NULL(_listener);
}
EventCustom eventOther("remove_child");
Director::getInstance()->getEventDispatcher()->dispatchEvent(&eventOther);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 执行 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
auto s1 = BugUnit::create();
auto s2 = BugUnit::create();
EventCustom event("remove_child");
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
OK
感谢您的配合,已经确认效果。
我会发个PR+Issue到仓库,引擎组会进行确认修复。
请暂时先避开在eventCallback中分发同一个消息的做法。