PDA

View Full Version : [AS3] Proper cleanup of custom cell renderer


rocker
07-05-2009, 08:15 AM
So I have a tilelist with a custom cell renderer, which is a movie clip with ICellRenderer implemented. I have all sorts of buttons, loaders, event listeners and timers in this custom cell renderer movie clip - in all it is a complicated cellrenderer.

When the tilelist is destroyed, I want to clean up all the cells, remove event listeners, stop timers etc so that these cells are properly garbage collected. The problem is, there is no way to call any method of these individual cells.

- Ideally, a solution would be to write a destructor function which does the job, but no- AS3 won't make your life that easy.
- I could have cleaned up when REMOVED_FROM_STAGE event fires in the cells, but strangely, this is fired so many times (with a button press etc) that I can not use it reliably.
- Calling tilelist.dataProvider.removeAll() merely sets the dataProvider to an empty array; doesn't help in cleaning up the items.

I have ran out of ideas. I have been struggling with this for several days without anything working. Can anyone please help me understand how can I cleanup the cells of a tilelist properly?

abeall
07-06-2009, 03:40 AM
As I understand it the Flash CS3/CS4 AS3 list components use pooling, which may explain why you get multiple REMOVED_FROM_STAGE events... but it is weird that clicking a button would trigger this.

Are you referencing the stage or anything outside the cell renderer class with your event listeners? Have you noticed any performance issues with how you have it now? Are you using weak references for your event listeners?

Have you you tried putting all your addEventListeners in ADDED_TO_STAGE and the removeEventListeners in REMOVED_FROM_STAGE and did that do what you want, regardless of the unexpected removes?

rocker
07-06-2009, 09:54 AM
Are you referencing the stage or anything outside the cell renderer class with your event listeners? Have you noticed any performance issues with how you have it now? Are you using weak references for your event listeners?


Yes, I have added an event listener on the parent class of the cellrenderer. But I have noticed that multiple REMOVED_FROM_STAGE are fired even when I comment this out. I have not noticed any performance degradation with/out this listener. All the listeners are weak references.


Have you you tried putting all your addEventListeners in ADDED_TO_STAGE and the removeEventListeners in REMOVED_FROM_STAGE and did that do what you want, regardless of the unexpected removes?

I am currently initializing the cell when set data() is called (and unfortunately, this too is called multiple times; no idea why. The only relief is, it is called with the same data). I will have to make some significant changes to make it work from ADDED_TO_STAGE It is an idea though. Thanks! I will give that too a shot.

DukeW
07-06-2009, 11:56 AM
You can use a global Array(using "public static") and push each instance of your custom cell renderer in to it(easiest to do from the constructor of you cell renderer), this will give you a direct reference to them so you can call you destructor.
Just don't forget to clear the array after your done, or it defeats its purpose :P

rocker
07-06-2009, 07:05 PM
I am currently initializing the cell when set data() is called (and unfortunately, this too is called multiple times; no idea why. The only relief is, it is called with the same data). I will have to make some significant changes to make it work from ADDED_TO_STAGE It is an idea though. Thanks! I will give that too a shot.

The problem with this approach is, ADDED_TO_STAGE is called before set data of the cell. I start to download images etc based on the cell data. I do not want start the loaders again on every ADDED.. to much drain on the already thin memory. Moreover, REMOVED_FROM_STAGE is called when (1) the button is pressed - unintentional call or (2) when the tilelist is being destroyed - proper.

If (2) I want to stop the loading images etc; not so in (1). There is really no way to distinguish what caused the REMOVED_FROM_STAGE event :(

Is there any tool which can show what references are active on the object and from where? I am using Flash CS3 and it is really a pain to debug such a problem without proper tools - it feels like I am just shooting in the dark.

rocker
07-06-2009, 07:13 PM
You can use a global Array(using "public static") and push each instance of your custom cell renderer in to it(easiest to do from the constructor of you cell renderer), this will give you a direct reference to them so you can call you destructor.
Just don't forget to clear the array after your done, or it defeats its purpose :P

I had thought of a similar idea originally. The bigger problem is, I have a bread crumbed hierarchy where multiple tilelists with this cell renderer are created.

The concept is an image browsing tool (you first see a tile of users who have shared images, and when a user is selected, her image folders are shown in the tile and so forth). So the same cell renderer is used in displaying all these. With a static array, it would be hard for me to tell, which cells ought to be destroyed and which not to be.