clean up your garbage
We don’t live in an ideal world where flash player’s garbage collector understands our brilliant ideas and our incredibly genius way of coding flex applications.
As you may already know, using weak event listeners with modules and pop-ups often results in memory leaks. It’s really painful to fully remove modules from memory if in-line styles, effects or focus enabled controls are present in the module.
Unfortunately, it’s all up to the individual developer. Here in Lab49 we use IDisposable interface that every disposable domain object, presentation model or view should implement.
package com.lab49.core
{
public interface IDisposable
{
function dispose() : void;
}
}
The main concept is very simple – every parent cleans up itself, its presentation model and calls ‘dispose’ method on its children if it’s applicable.
<?xml version="1.0" encoding="utf-8"?>
<TitleWindow xmlns="http://ns.adobe.com/mxml/2009"
implements="com.lab49.core.IDisposable"
layout="absolute"
close="dispose()">
<Script>
<![CDATA[
import com.lab49.core.IDisposable;
import com.lab49.example.model.BasePresentationModel;
[Bindable]
public var model : BasePresentationModel;
public function dispose() : void
{
//remove all event listeners here
//stop all effects
//clean up model
if ( model )
{
model.dispose();
}
//Clean up children
var children : Array = getChildren();
for each( var child : DisplayObject in children )
{
if ( child is IDisposable )
{
IDisposable( child ).dispose();
}
}
}
]]>
</Script>
</TitleWindow>
Решение хорошее, но есть проблема – таким образом придется расширять все компоненты.
I agree that this isn’t an ideal solution, but how often you are using standard components without extending it?
Примерно 30-40% – это стандартные компоненты. Но цена нормальная, т.к. в крупных приложениях проблема очистки памяти – одна из трудоемких (как не печально).
Однако, хочу заметить, что в компонентах могут быть и элементы уровня Sprite. Их так же придется помещать в “обертку”.
Гораздо более интересный вопрос – что нужно вычищать в самом методе dispose(). Список получился не плохой –
# //remove all event listeners here
# //stop all effects
# //clean up model
а как насчет программного биндинга (BindingUtils.bindSetter(…))?
I totally agree, that this is a really long list but it’s the best option we have so far.
Regarding Binding – I’m not a big fan of in-line binding so I’d rather use events or BindingUtils with appropriate disposal like
private var watcher : ChangeWatcher = BindingUtils.bindSetter(....); //.... later in dispose method public function dispose() : void { //some other disposal... //.... if ( watcher && watcher.isWatching() ) { watcher.unwatch(); } watcher = null; }