timer.performWithDelay interrupted error

Hi,

I can’t really get my head around this one. I’m using a timer.performWithDelay to spawn multiple sprite animations that rain down over the screen. If I let the whole timer run until it’s finished all is well. But if I go to another scene (storyboard) while the timer is still running I get an error in the new scene - “Attempt to call method ‘removeSelf’ (a nil value)”.

So the timer is somehow still running - or at least spawnConfetti() still is and is trying to remove an object from the display group that is no longer there because of the scene change.

I’ve tried to cancel the timer but it has no effect.

Any ideas?

Best

Fredrik

local function spawnConfetti() local confettiSpawn = display.newSprite( mySheet, sequenceData ) confettiSpawn.x = math.random(-100, 1200); confettiSpawn.y = -40; confettiSpawn:play() group:insert( confettiSpawn ) transition.to( confettiSpawn, { time = math.random(3000, 6000), x = math.random(-100, 1200) , y = screenH + 50, alpha = 0, onComplete = function(obj) if obj then obj:removeSelf() obj = nil end end } ); end local countSprites = 100 local tmr = timer.performWithDelay(100, spawnConfetti, countSprites)

Unfortunately it is not enough to do _ if obj _ for the check. 

Try out a debug print table function to inspect the sprite, my favorite: http://pastebin.com/GPtqxu2F

Then you see that there is " _proxy " table key, in my experience that is a reliable way to do check if it is a valid object. So change you onComplete:

[lua]onComplete = function(obj) if obj and obj._proxy then obj:removeSelf() obj = nil end end } )[/lua]

I would love to hear if there is a better way than this though.

It’s good method. The key point is that when you perform obj:removeSelf() then the answer for if(obj) is still true.
The reason is that graphics objects are like lua tables with image data attached to it (hidden in _proxy property).
When you call removeSelf() then only memory containing image will be free, leaving skeleton table. Checking table with if will always return true.
This is the reason you always have to removeSelf() and then nil object to free whole memory.

Ahh, excellent! I think it is safe to say I wouldn’t have figured that out myself. It didn’t even occur to me.

Unfortunately the solution brings up a new issue (and with it some doubt as to if this was a good solution to begin with). While the onComplete now runs fine the group:insert will throw the same error. I tried wrapping it in a similar function but it doesn’t work. I donät know if it’s because Storyboard will get the request and by the time it’s ready to insert the object it’s already gone perhaps?

Unfortunately it is not enough to do _ if obj _ for the check. 

Try out a debug print table function to inspect the sprite, my favorite: http://pastebin.com/GPtqxu2F

Then you see that there is " _proxy " table key, in my experience that is a reliable way to do check if it is a valid object. So change you onComplete:

[lua]onComplete = function(obj) if obj and obj._proxy then obj:removeSelf() obj = nil end end } )[/lua]

I would love to hear if there is a better way than this though.

It’s good method. The key point is that when you perform obj:removeSelf() then the answer for if(obj) is still true.
The reason is that graphics objects are like lua tables with image data attached to it (hidden in _proxy property).
When you call removeSelf() then only memory containing image will be free, leaving skeleton table. Checking table with if will always return true.
This is the reason you always have to removeSelf() and then nil object to free whole memory.

Ahh, excellent! I think it is safe to say I wouldn’t have figured that out myself. It didn’t even occur to me.

Unfortunately the solution brings up a new issue (and with it some doubt as to if this was a good solution to begin with). While the onComplete now runs fine the group:insert will throw the same error. I tried wrapping it in a similar function but it doesn’t work. I donät know if it’s because Storyboard will get the request and by the time it’s ready to insert the object it’s already gone perhaps?