table count always grows even after display.remove

I have a timer which calls a function that creates objects off screen, moves them onto the screen, and then removes them.  

Objects are moved with transition.to and then in onComplete I am doing display.remove.  Here is a code snippet:

local objects = {} local function createObject(position, spd) print("object count is: " .. #objects) local tmp = display.newImageRect(dsp\_grp, "sprites/object.png", 211, 244) tmp.x, tmp.y = position.startX, position.startY object\_transitions[#object\_transitions + 1] = transition.to(tmp, {time = spd, x = position.endX, onComplete = display.remove}) objects[#objects + 1] = tmp end timer.performWithDelay(frequency, function() createObject(position, speed) end, -1)

My question is:   Why is #objects always growing every time I call the print statement?  I thought after display.remove the object no longer exists in the table so the table size shouldn’t keep growing?  

Can anyone point out what I am missing?

display.remove() doesn’t actually remove the Lua table, it only removes the associated display object.

In order to fully remove/clear an object, you’ll have to set the associated variable or table entry to nil, e.g.

local object = {} object[#object+1] = display.newRect( 0, 0, 100, 100 ) display.remove( object[#object] ) -- By setting the table entry to nil, it becomes fully cleared. object[#object] = nil

Since I am using onComplete in the transition.to to call display.remove, how would I know which particular entry in the objects table to set to nil? 

Firstly, do you even need an objects table, do you do anything with it?

If so, I guess you’ll have to assign each object a unique ID, then to delete iterate through the objects table (backwards) and check the id, as soon as you find the right one, use table.remove and break from the loop.

I thought it was good practice to store everything in case I need to do something in the future.  Ex:  Pause the game, restart the level, etc… 

Maybe I should back up and ask a more fundamental question… When I need to create multiple objects and would like to keep track of them, like enemies, or astroids, etc… Is there a method that’s considered best practice? 

  1. If you’re going to store objects in a table that you need to remove later, store them by ID.
     

  2. Use finalize to self-remove from the table.
     

  3. You will need to change the way you iterate the table however.  Since storing by name is not compatible with numeric table iteration

    local objects = {} local obj = display.newCircle(…) objects[obj] = obj function obj:finalize( event ) objects[self] = nil end obj:addEventListener( “finalize” )

Later you can iterate the table like this:
 

for \_,obj in pairs( objects ) -- do something with obj end

You can count entries in the table like this:

local count = 0 for \_,obj in pairs( objects ) count = count + 1 end

You need to remove it from the correct position in the table.

[lua]

local function clearFromTable(t,o) – t is table ; o is object to remove

    local pos = table.indexOf( t, o )

    if (pos ~= nil) then 

      table.remove( t, pos)

    end

end

[/lua]

Storing them by ID definitely has some advantages here, but I still prefer storing then by number indexes as that is more natural for me at the moment.  There was a robust debate about this a year ago and @RoamingGamer made some good points.  I have started to switch over to indexing by ID for some of my new modules.

I believe if I were to start from scratch today I might get in the habit of using ID’s as indexes.

I make a ton of #table comparisons to that is my main reason for staying with numbers at the moment.

Thanks all for the advice.  

@sporkfin - Just found that thread from RoamingGamer.  Think I will go the storing by ID route and see how it works out.

@RoamingGamer  -  Thanks for the example, will give it a try.