3.81lua严重crash bug

3.81版本 lua有个非常严重的bug: 两个继承于Node的A与B 1. 在layer的init里 new A add A, 2.在onTouch时 new B removeA 3.再次touch时 removeB 此时一定会挂在Node的析构函数这一句CCASSERT(!_running, “Node still marked as running on node destruction! Was base class onExit() called in derived class onExit() implementations?”);

我分析在step2 new B 与 removeA 这里,c++的内存分配上有问题,把A的内存分配给了B 导致了最终的奇怪crash

示例代码如下
local a = myClassA:new()
self:addChild(a)
self.a = a

local function onTouchBegan(touch, event)
if self.a then
local b = myClassB:new()
self:addChild(b)
self.b = b

    self.a:removeFromParent()
    self.a = nil
elseif self.b then
    self.b:removeFromParent()
    self.b = nil
end
return true

end

local listener = cc.EventListenerTouchOneByOne:create()
listener:setSwallowTouches(true)
listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)

local eventDispatcher = self:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)

:11::11::11::11::11::11:你一定在逗我 你的代码我拷贝过去 没有什么问题 如果贴代码 贴全点 把myclass什么的都改对

local MainScene = class(“MainScene”, cc.load(“mvc”).ViewBase)

local BEEvents = {}
BEEvents.lockEvent= “baselayer_lock_event”
BEEvents.unlockEvent = “baselayer_unlock_event”

local MyClassBase = class(“MyClassBase”, function()
return display.newLayer()
end)

function MyClassBase:ctor()
self:enableNodeEvents()
end

function MyClassBase:onEnter()
–lock others
self:lock()

local dispatcher = self:getEventDispatcher()

--register lock msg
local lockListener = cc.EventListenerCustom:create(BEEvents.lockEvent, function(eventCustom)
    print("lock message")
end)
dispatcher:addEventListenerWithSceneGraphPriority(lockListener, self)

--register unlock msg
local unlockListener = cc.EventListenerCustom:create(BEEvents.unlockEvent, function(eventCustom)
    print("unlock message")
end)
dispatcher:addEventListenerWithSceneGraphPriority(unlockListener, self)

end

function MyClassBase:lock()
local lockEvent = cc.EventCustom:new(BEEvents.lockEvent)
local dispatcher = self:getEventDispatcher()
dispatcher:dispatchEvent(lockEvent)
end

function MyClassBase:unlock()
local unlockEvent = cc.EventCustom:new(BEEvents.unlockEvent)
local dispatcher = self:getEventDispatcher()
dispatcher:dispatchEvent(unlockEvent)
end

function MyClassBase:onExit()
self:unlock()
end

–classA
local MyClassA = class(“MyClassA”, MyClassBase)

function MyClassA:ctor()
MyClassA.super.ctor(self)

local bkg = cc.LayerColor:create(cc.c4b(255, 255, 0, 77))
self:addChild(bkg)
self.bkgLayer = bkg

end

function MyClassA.show()
if not MyClassA.currentActivity then
local parent = cc.Director:getInstance():getRunningScene()
local activity = MyClassA.new()
parent:addChild(activity, 100000)
MyClassA.currentActivity = activity
end

end

function MyClassA.hide()
if MyClassA.currentActivity then
MyClassA.currentActivity:removeFromParent()
MyClassA.currentActivity = nil
end
end

local MyClassB = class(“MyClassB”, function( … )
return display.newNode()
end)

function MainScene:onCreate()
local function onTouchBegan(touch, event)
print(“touch me”)

    if self.state == nil then
        MyClassA.show()
        self.state = 1

        print("step 1: crete a")
    elseif self.state == 1 then
        self.b = MyClassB.new()
        local scene = cc.Director:getInstance():getRunningScene()
        scene:addChild(self.b)

        MyClassA.hide()
        self.state = 2

        print("step 2: create b then remove a")--and then it must be crash on c++ ~Node()
    else
        self.b:removeFromParent()
        self.state = nil

        print("step 3: remove b now")
    end

    return true
end

local listener = cc.EventListenerTouchOneByOne:create()
listener:setSwallowTouches(true)
listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)

local eventDispatcher = self:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)

end

return MainScene

上面是完整代码,之所以之前没发出来 是因为产生环境太复杂,我单独花了点时间构造了一个类似的

你只需要新建一个lua工程,替换掉里面mainScene的内容即可重现:点击屏幕两次,第二次必崩

:10: 坐等解惑