A similar question. Tell me what I’m doing wrong. In some function, in a loop (10x10 matrix creation), I create objects and hang listeners, I put the objects in a table:
for i = 1, 10 do
for j = 1, 10 do
playerCell: addEventListener (“tap”, placeSph)
playerTab [i] [j] = playerCell
end
end
In another function, I wanted to remove the listeners with this code:
for i = 1, #playerTab do
for j = 1, #playerTab [i] do
playerTab [i] [j]:removeEventListener (“tap”, placeSph)
end
end
Returns nil, does not remove the listener. Maybe I’m calling incorrectly via :
Is the error this, “attempt to index field ‘?’ (a nil value)”?
If yes, maybe the codes below may help. If not, what is the error message?
--add listeners
for i = 1, 10 do
playerTab[ i ] = {}
for j = 1, 10 do
playerCell:addEventListener( "tap", placeSph )
playerTab[ i ][ j ] = playerCell
end
end
-- remove listeners
for i = 1, #playerTab do
for j = 1, #playerTab[ i ] do
playerTab[ i ][ j ]:removeEventListener ( "tap", placeSph )
end
end
@yashureg Avoid this kind of table creation if possible, since it can lead to some mistakes.
@luantiang approach is better because if you decide to change the number of rows or cols you don’t need to count how many nested tables you already have and add more manually. You may also forget to do that or count them wrong.
You are correct print (placeSph) gives nil value. I think I have a knowledge gap about this. Did the garbage collector destroy the reference to placeSph? It was declared as a local function in the main file along with other functions that work. Is this connected with the fact that placeShp is hung on the playerCell, which are accessed only as an element of the table in which I put all of them?
The garbage collector clean the memory that is not being referenced by any variable, and it doesn’t break references by its own.
If the declaration and use of placeSph is in the same file, this should be happening because of closures. If you are declaring it inside a function, it is going to be accessible only inside that function. Make sure to declare it in the same or in a higher closure to be accessible when you remove the event listeners.
Also, try to avoid keeping all your code in main.lua.
Main must be only the initialization file of all your game. And your files must rarely be over 1000 lines. It will help you debugging and keeping your code clean.
If you are removing these listeners just before you delete the object, then do it the easy way, use a finalize listener to do the cleanup.
Here is a standalone example of a display object, cleaning up:
Local Listener - Touch listener for this example.
Outstanding Timer
local function onTouch( self, event )
-- body of listener
end
local function onFinalize( self, event )
self:removeEventListener( 'touch' )
timer.cancel(self.myTimer)
end
local obj = display.newCircle( ... )
-- Adding the touch listener (local style listener)
obj.touch = onTouch
obj:addEventListener( 'touch' )
-- Start a timer and track the handle in field on object
obj.myTimer = timer.peformWithDelay( 10000, function() ... end )
... later, just delete the object and it will clean up after itself
display.remove( obj )
No, I am not writing in main. In the file with the screen of the immediate game, I have declared all the functions one by one as local function. That is, the declaration of the placeSph function is no different from the rest. Probably the problem is what I am doing:
local function playerField ()
for i = 1, 10 do
for j = 1, 10 do local playerCell = display.newImageRect( mainGroup, objectSheet, 10, cellSize, cellSize )
playerCell:addEventListener( “tap”, placeSph )
playerTab[i][j] = playerCell
end
end
end
Should I declare playerCell outside of the for loop, or even outside of this function as a local variable?
I am not deleting objects. The idea was that I create a field of game cells on which the player places objects (like in a sea battle game). Until the number of objects exceeds 6, the listener adds them (individual objects on top of the cells are simply at the same coordinates). As soon as there are 6 of them, the game with AI starts automatically and the listener is not needed on the player’s field (he has already set everything, and AI just randomly selects a cell and checks or sets its properties).