Should tableView:deleteAllRows() dispose of display objects in the rows it is deleting?

I found a memory leak in my project and tracked down to tableView:deleteAllRows() does not dispose of the display objects inside the rows it is deleting.

Is this expected behavior or a bug?

My test case (requires test.jpg):

[lua]

display.setStatusBar( display.HiddenStatusBar )

local widget = require( “widget” )

local tableView

local function printMemory()

    print( “Tex:” … math.floor(system.getInfo( “textureMemoryUsed” )*0.000001*1000)*0.001 … “MB”)

end

local function onRowRender( event )

    local testImage = display.newImageRect(event.row, “test.jpg”, 20,20)

    testImage.x, testImage.y = 100, 20

end

tableView = widget.newTableView {

    onRowRender = onRowRender,

}

tableView:insertRow{rowHeight = 80}

printMemory()

tableView:deleteAllRows()

printMemory()

[/lua]

Hi Jon,

Doesn’t look like it has to do with the tableView, more like image files are cached in memory by Corona.

Here is a small example that shows the same texture being kept in memory

printMemory()

local  testImage = display.newImageRect(“testimage.png”, 20,20)

printMemory()

testImage:removeSelf()

testImage = nil;

printMemory()

I also tried your code in a loop (re-creating the table and rows a number of times) and after the first time the image is loaded, it does not show any increase in the texture memory, so it is reusing the same image

Cheers,

Atanas

Thanks for the reply.  You are probably right, its not a memory leak. My problem was a bit different than what I said really, sorry about that.

I am looping a transition on an object in the row, and it kept looping if the item was available. So even after deleting the row the loop went on and all the items in the row seem to be available after doing deleteAllRows. 

I can do things differently so it wont happen, was just wondering.

So for example this:

[lua]

local widget = require( “widget” )

local rowTitle 

local function onRowRender( event )

    rowTitle = display.newText( event.row, “Table test”, display.contentWidth/2, event.row.contentHeight * 0.5, nil, 14 )

end

local tableView = widget.newTableView {

    onRowRender = onRowRender,

}

tableView:insertRow{rowHeight = 80}

tableView:deleteAllRows()

if rowTitle then 

    – Performing a transition on an object that I thought should no longer be available after deleteAllRows

    transition.to(rowTitle, {delay = 500, time = 500, onComplete = function() print(“transition completed”, rowTitle) end})

end

– If you inspect  the rowTitle after all this it still looks the same as before deleting all rows

–{

–|  _class = {

–|  |  removeEventListener = “function: 0x7f8f799451e0”,

–|  |  addEventListener = “function: 0x7f8f79945180”,

–|  |  __index = {} – Value._class (self reference)

–|  },

–|  _proxy = “userdata: 0x7f8f79962628”,

–}

[/lua]

Hi Jon,

In your case, the object is still in memory because the variable is still in scope and you will need to eventually set it to nil. Also, Corona is garbage collected, and I guess you can have “artifacts” - the object was disposed but just the memory it was pointing at still contains the same data and the garbage collector has not reclaimed the memory. If you keep allocating more memory it will eventually get overriden

Atanas

Hi Jon,

Doesn’t look like it has to do with the tableView, more like image files are cached in memory by Corona.

Here is a small example that shows the same texture being kept in memory

printMemory()

local  testImage = display.newImageRect(“testimage.png”, 20,20)

printMemory()

testImage:removeSelf()

testImage = nil;

printMemory()

I also tried your code in a loop (re-creating the table and rows a number of times) and after the first time the image is loaded, it does not show any increase in the texture memory, so it is reusing the same image

Cheers,

Atanas

Thanks for the reply.  You are probably right, its not a memory leak. My problem was a bit different than what I said really, sorry about that.

I am looping a transition on an object in the row, and it kept looping if the item was available. So even after deleting the row the loop went on and all the items in the row seem to be available after doing deleteAllRows. 

I can do things differently so it wont happen, was just wondering.

So for example this:

[lua]

local widget = require( “widget” )

local rowTitle 

local function onRowRender( event )

    rowTitle = display.newText( event.row, “Table test”, display.contentWidth/2, event.row.contentHeight * 0.5, nil, 14 )

end

local tableView = widget.newTableView {

    onRowRender = onRowRender,

}

tableView:insertRow{rowHeight = 80}

tableView:deleteAllRows()

if rowTitle then 

    – Performing a transition on an object that I thought should no longer be available after deleteAllRows

    transition.to(rowTitle, {delay = 500, time = 500, onComplete = function() print(“transition completed”, rowTitle) end})

end

– If you inspect  the rowTitle after all this it still looks the same as before deleting all rows

–{

–|  _class = {

–|  |  removeEventListener = “function: 0x7f8f799451e0”,

–|  |  addEventListener = “function: 0x7f8f79945180”,

–|  |  __index = {} – Value._class (self reference)

–|  },

–|  _proxy = “userdata: 0x7f8f79962628”,

–}

[/lua]

Hi Jon,

In your case, the object is still in memory because the variable is still in scope and you will need to eventually set it to nil. Also, Corona is garbage collected, and I guess you can have “artifacts” - the object was disposed but just the memory it was pointing at still contains the same data and the garbage collector has not reclaimed the memory. If you keep allocating more memory it will eventually get overriden

Atanas