Trouble with removing listeners

I have some trouble concerning listeners on a object that can be removed in 2 different ways. So I’ve used the Gary Sims tutorial on making android games with the corona sdk: http://www.androidauthority.com/writing-your-first-android-game-623386. Now the code from the tutorial itself worked without problems, however I tried to change some things from there on so that the program behaves a little different. For starters I didn’t want the object to fall but rather appear randomly on the screen so I removed the physics. Also, since the objects are not removed now after they leave the screen I wanted to remove them after a certain amount of time, however now the object do remove themselves after the time, however if I remove them after clicking on them it reports an error “attempt to call method “removeSelf” (a nil value)”.

I tried in two separate ways for both the bomb and the balloon, however the error is the same and it points to the “timer.performWithDelay( 800, function() self:removeSelf() end, 1)” and “timer.performWithDelay( 800, function() balloon:removeSelf() end, 1)” respectively.

I’ll post the complete code bellow, please tell me what am I doing wrong.

halfW = display.contentWidth\*0.5 halfH = display.contentHeight\*0.5 local bkg = display.newImage( "night\_sky.png", halfW, halfH ) score = 0 scoreText = display.newText(score, halfW, 10) local function balloonTouched(event) if ( event.phase == "began" ) then event.target:removeSelf() score = score + 1 scoreText.text = score end end local function bombTouched(event) if ( event.phase == "began" ) then event.target:removeSelf() score = math.floor(score \* 0.5) scoreText.text = score end end local function offscreen(self, event) if(self == nil) then return end Runtime:removeEventListener( "enterFrame", self ) timer.performWithDelay( 800, function() self:removeSelf() end, 1) end local function addNewBalloonOrBomb() local startX = math.random(display.contentWidth\*0.1,display.contentWidth\*0.9) local startY = math.random(display.contentHeight\*0.1,display.contentHeight\*0.9) if(math.random(1,10)==1) then -- BOMB! local bomb = display.newImage( "bomb.png", startX, startY) bomb.enterFrame = offscreen bomb:addEventListener( "touch", bombTouched ) Runtime:addEventListener( "enterFrame", bomb ) else -- Balloon local balloon = display.newImage( "red\_balloon.png", startX, startY) balloon:addEventListener( "touch", balloonTouched ) timer.performWithDelay( 800, function() balloon:removeSelf() end, 1) end end addNewBalloonOrBomb() timer.performWithDelay( 500, addNewBalloonOrBomb, 0 )

The problem seems to be that you’re calling removeSelf() twice – and since that method frees up the object for garbage collection, it’s likely that it will be nil the next time you access it.

This isn’t the world’s best programming practice, but you could add a check in your timer callback to make sure the object isn’t nil. For example:

timer.performWithDelay( 800, function() if (balloon ~= nil and balloon.removeSelf ~= nil) then balloon:removeSelf() end end, 1)

Thanks, that worked.

The problem seems to be that you’re calling removeSelf() twice – and since that method frees up the object for garbage collection, it’s likely that it will be nil the next time you access it.

This isn’t the world’s best programming practice, but you could add a check in your timer callback to make sure the object isn’t nil. For example:

timer.performWithDelay( 800, function() if (balloon ~= nil and balloon.removeSelf ~= nil) then balloon:removeSelf() end end, 1)

Thanks, that worked.