Problem with tables and function calls after removing the table entry.

 I’m facing a problem , even though when I remove a container and set it to nil the function container.twoSquareMove() seems to be executing.

The scenario is I’m creating a random set of obstacles. If the current obstacle created is similar to the previous one, I call display.remove(container) and I assign nil value to it.

For example:-

containers[#containers + 1] = normal.twoSquares(container, currHeight, player) -- This is just for reference, I'm not calling same function again and again. if containers[#containers].name == containers[#containers-1].name then display.remove(containers[#containers]) containers[#containers] = nil end

i even tried adding a condition statement with a timer: 

timer.performWithDelay(1000, function() if container ~= nil then container.twoSquareMove() end end) 

Yet it’s executes

function \_M.twoSquares(container, currHeight, player) local container = container randomizer.callRandom(container,2) container.start = measure.cliff2 container.ender = measure.cliff4 if random(2) == 2 then container.start = measure.cliff4 container.ender = measure.cliff6 end local square = {} square[1] = display.newRect(container, container.start,30, 60,60) square[1].path = 1 square[2] = display.newRect(container, container.ender,210, 60,60) square[2].path = 2 container.numElements = container.numChildren container.row = 2 container.name = "ts" function container.twoSquareMove() -- this is the function getting called, even after I assign nil to the container. local start = container.start local ender = container.ender for i=1, 2 do if square[i].path == 1 then transition.to(square[i], { time = 500, delay = 500, x = ender, onComplete = function() square[i]:setFillColor(1,0,0); transition.to(square[i], { time = 500, delay = 500, y = 210, onComplete = function() square[i]:setFillColor(0,1,0); square[i].path = 2; end}) end}) elseif square[i].path == 2 then transition.to(square[i], { time = 500, delay = 500, x = start, onComplete = function() square[i]:setFillColor(0,0,1); transition.to(square[i], { time = 500, delay = 500, y = 30, onComplete = function() square[i]:setFillColor(1,1,0); square[i].path = 1; end}) end}) end end timer.performWithDelay(2050, function() container.twoSquareMove() end, 1) end container.twoSquareMove() -- this is the function call which I altered as mentioned above.

I’m current using a workaround using a property and I set it to false when the container is getting removed, yet the property works as expected, even though i set the container to nil. I’m assuming the nil value isn’t getting set to the container or I’m just setting nil to a reference of the container and not actually to it.

Please advice.

you’ve created a self-referencing closure twoSquareMove() around “container” within the local scope of twoSquares(), so THAT is what’s holding onto the reference, NOT the array.

then you create a timer (which will hold a reference to the closure, and thus the container) which returns to the same closure,… to restart the timer - repeat forever, never dropping the reference.

if you wish to keep this structure, then suggest you store the handle of the timer (as a member of the container) and explicitly cancel it when destroying the container.

aside:

function \_M.twoSquares(container, currHeight, player) local container = container --\<\<this probably doesn't do what you imagine it does

oh, I understand now. i thought since the container.twoSquareMove() is a dotMethod it will be automatically removed as I set nil to the container.

And about the local container = container thing, your right. I read about localizing and stuff, but I think it only matters if there are loops in the function.

I’ll do as you have advised on creating a handle of the timer.

Thanks a lot davebollinger.

you’ve created a self-referencing closure twoSquareMove() around “container” within the local scope of twoSquares(), so THAT is what’s holding onto the reference, NOT the array.

then you create a timer (which will hold a reference to the closure, and thus the container) which returns to the same closure,… to restart the timer - repeat forever, never dropping the reference.

if you wish to keep this structure, then suggest you store the handle of the timer (as a member of the container) and explicitly cancel it when destroying the container.

aside:

function \_M.twoSquares(container, currHeight, player) local container = container --\<\<this probably doesn't do what you imagine it does

oh, I understand now. i thought since the container.twoSquareMove() is a dotMethod it will be automatically removed as I set nil to the container.

And about the local container = container thing, your right. I read about localizing and stuff, but I think it only matters if there are loops in the function.

I’ll do as you have advised on creating a handle of the timer.

Thanks a lot davebollinger.