How to remove every child in DisplayGroup?

options = {} options.text = "Hello World" options.x = 150 options.y = 150 local g = display.newGroup() local myText1 = display.newText( options ) g:insert(myText1) local myText2 = display.newText( options ) g:insert(myText) local myText3 = display.newText( options ) g:insert(myText3) local myText4 = display.newText( options ) g:insert(myText4) local myText5 = display.newText( options ) g:insert(myText5) . . . local myText10000 = display.newText( options ) g:insert(myText100) for i=g.numChildren,1,-1 do local child = g[i] child.parent:remove( child ) child = nil end if myText10000 then print("I am still here.") // will be printed end

In this way, every textObject will be disappear on the screen.

But “I am still here.” will be printed. That means every textObject is still exist.

So is this the appropriate way to remove every child from a group?  And if this is not the right way, what should I do.

Thank you for the time. 

Not sure if you have a typo here, or in your actual code:

local myText10000 = display.newText( options ) g:insert(myText100)

The object is called myText10000, but you are inserting an object called myText100. However if you don’t have an object called “myText100”, I would expect the insertion to throw an error.

Other than that, the way you have set up your child removal seems correct to me - I’ve been doing it this way for a couple of years.

It’s because display objects are like extensions of Lua tables (just for simplicity) and tables are passed by reference. What’s more, Lua has so called garbagecollector which automatically removes not used variables/tables. But there is one condition for it to work. There has to be 0 references to variable/table.

Function parent.remove() or removeSelf() (which is better because for groups it triggers removeSelf for each child and you do not have to iterate yourself) frees only part of memory which keeps image data (treat text here also as image) but barebone table still remains in memory (it like skeleton on which display objects was build).

So summing up:

-You create some texts (in details you create table with image inside it)
-in loop you remove images from memory leaving barebone tables
-garbagecollector kicks in an wants to remove this empty tables
-garbagecollector cannot remove table because number of references to it is greater then 0 (myText10000 is keeping reference to one of tables)
-you check if there is something under myText10000 variable and because it keeps reference to barebone table then it returns true.

This is the reason that object:removeSelf() and object = nil usually comes in pairs.
You can check that trying to execute in condition myText10000:setFillColor or any text specific function will throw an error because there is something (barebone table) but it no longer is display object.

Thank you guys so much for telling me this.

So i guess, set every

myText = nil 

is not necessary?

It is usually necessary if it is not in some local scope,

For example:

local function drawText() local myText = display.newText(...) end

here you do not have to nil variable because it will be niled when function ends (so just removeSelf on parent group will be enough). Otherwhise you should nil to do not have memory leaks.

Thanks a lot for your patient, and what about a local variable in a class’s function?

If the class didn’t destroy, do I also need to set the variable as nil?

Like:

AClass = {} function AClass:showText( ) local myText = ... end

Function is function - no difference if in class or not

When variable goes out of scope then reference is automatically niled leaving only display object ‘stored in screen memory’

This can be used to loop through all the items in a corona display group.

You should make sure the object is a real display object before you do any display stuff to it. (Usually it’s ALL display group stuff, unless you’ve been stashing some of your own vars in the group).

[lua]

local function loopChildren(this)

    for index, value in pairs(this) do
        if( type(value) == “table” ) then
            if( value.x ~= nil ) then

                – NOTE: x can be any property, or method – to be sure it is attached to screen, you can use value.removeSelf as well
                --print("value.x == ", value.x)
                value.x = value.x + 200    – Move them all a little or something
                value.y = value.y + 200

                –

                – If you want to get fancy and do subgroups / recursion, this is the place…
            end
        end
 

end

[/lua]

display.remove( obj ) will check for the objects existence before removing it which can be nice.

What piotrz55 said is very important to remember.  You can remove visible items, but an empty table can possibly remain under certain circumstances, causing lots of headaches.

Also, what is the purpose of:

[lua]child.parent:removeSelf( child )[/lua] ?

You should be able to do:

[lua]

for i=g.numChildren,1,-1 do

 local child = g[i]

 child:removeSelf() – or display.remove( child )

 child = nil

end

[/lua]

Not sure if you have a typo here, or in your actual code:

local myText10000 = display.newText( options ) g:insert(myText100)

The object is called myText10000, but you are inserting an object called myText100. However if you don’t have an object called “myText100”, I would expect the insertion to throw an error.

Other than that, the way you have set up your child removal seems correct to me - I’ve been doing it this way for a couple of years.

It’s because display objects are like extensions of Lua tables (just for simplicity) and tables are passed by reference. What’s more, Lua has so called garbagecollector which automatically removes not used variables/tables. But there is one condition for it to work. There has to be 0 references to variable/table.

Function parent.remove() or removeSelf() (which is better because for groups it triggers removeSelf for each child and you do not have to iterate yourself) frees only part of memory which keeps image data (treat text here also as image) but barebone table still remains in memory (it like skeleton on which display objects was build).

So summing up:

-You create some texts (in details you create table with image inside it)
-in loop you remove images from memory leaving barebone tables
-garbagecollector kicks in an wants to remove this empty tables
-garbagecollector cannot remove table because number of references to it is greater then 0 (myText10000 is keeping reference to one of tables)
-you check if there is something under myText10000 variable and because it keeps reference to barebone table then it returns true.

This is the reason that object:removeSelf() and object = nil usually comes in pairs.
You can check that trying to execute in condition myText10000:setFillColor or any text specific function will throw an error because there is something (barebone table) but it no longer is display object.

Thank you guys so much for telling me this.

So i guess, set every

myText = nil 

is not necessary?

It is usually necessary if it is not in some local scope,

For example:

local function drawText() local myText = display.newText(...) end

here you do not have to nil variable because it will be niled when function ends (so just removeSelf on parent group will be enough). Otherwhise you should nil to do not have memory leaks.

Thanks a lot for your patient, and what about a local variable in a class’s function?

If the class didn’t destroy, do I also need to set the variable as nil?

Like:

AClass = {} function AClass:showText( ) local myText = ... end

Function is function - no difference if in class or not

When variable goes out of scope then reference is automatically niled leaving only display object ‘stored in screen memory’

This can be used to loop through all the items in a corona display group.

You should make sure the object is a real display object before you do any display stuff to it. (Usually it’s ALL display group stuff, unless you’ve been stashing some of your own vars in the group).

[lua]

local function loopChildren(this)

    for index, value in pairs(this) do
        if( type(value) == “table” ) then
            if( value.x ~= nil ) then

                – NOTE: x can be any property, or method – to be sure it is attached to screen, you can use value.removeSelf as well
                --print("value.x == ", value.x)
                value.x = value.x + 200    – Move them all a little or something
                value.y = value.y + 200

                –

                – If you want to get fancy and do subgroups / recursion, this is the place…
            end
        end
 

end

[/lua]

display.remove( obj ) will check for the objects existence before removing it which can be nice.

What piotrz55 said is very important to remember.  You can remove visible items, but an empty table can possibly remain under certain circumstances, causing lots of headaches.

Also, what is the purpose of:

[lua]child.parent:removeSelf( child )[/lua] ?

You should be able to do:

[lua]

for i=g.numChildren,1,-1 do

 local child = g[i]

 child:removeSelf() – or display.remove( child )

 child = nil

end

[/lua]