As a part of trying to tackle a memory leak in our application, we discovered that for every SkinnableComponent
, the skinDestructionPolicy
is set to "never"
by default.
This means that when using static skin parts, the skin is forever detained in memory.
Furthermore, the override of a partRemoved() in the host component will never be triggered.
Hence, event listeners we add in the partAdded() override are not removed, which effectively causes views and skins to be kept in memory.
When doing a lot of view switches this is just not acceptable.
Here is an example of of how we are working around this now:
public class ViewA extends SkinnableComponent
{
[SkinPart(required = "true")]
public var labelA:Label;
[SkinPart(required = "true")]
public var buttonA:Button;
public function ViewA()
{
super();
mx_internal::skinDestructionPolicy = 'auto';
}
override protected function getCurrentSkinState():String
{
return super.getCurrentSkinState();
}
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
trace("ViewA::partAdded " + partName);
if (instance == buttonA)
{
buttonA.addEventListener(MouseEvent.CLICK, buttonClickedHandler);
}
}
override protected function partRemoved(partName:String, instance:Object):void
{
trace("ViewA::partRemoved " + partName);
if (instance == buttonA)
{
buttonA.removeEventListener(MouseEvent.CLICK, buttonClickedHandler);
}
super.partRemoved(partName, instance);
}
override public function stylesInitialized():void
{
setStyle("skinClass", ViewASkin);
}
}
However, using the mx::internal
way to circumvent this behavior seems rather odd to me.
Documentation about this is scarce as well, so any ideas will be very welcome.
Cheers