2

作为尝试解决应用程序中内存泄漏的一部分,我们发现对于每个SkinnableComponent,默认skinDestructionPolicy设置为"never"

这意味着当使用静态皮肤部件时,皮肤将永远留在记忆中。
此外,永远不会触发主机组件中 partRemoved() 的覆盖。因此,我们在 partAdded() 覆盖中添加的事件侦听器不会被删除,这实际上会导致视图和皮肤保留在内存中。

在进行大量视图切换时,这是不可接受的。

以下是我们现在如何解决此问题的示例:

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);
    }
}

但是,使用这种mx::internal方式来规避这种行为对我来说似乎很奇怪。关于这方面的文档也很少,所以任何想法都会受到欢迎。

干杯

4

1 回答 1

2

根据我的经验,mx::internalFlex SDK 中命名空间的使用通常意味着:“你可以使用这个功能,如果你知道你在做什么,还有我们(Adobe,或者未来的 Apache 社区)不保证此 API 在 Flex 的未来版本中永远不会改变”。

所以它的使用没有真正的问题,除非你非常关心向后兼容性。如果你真的想避免使用它,你总是可以skinDestructionPolicy="auto"在你的子类中实现的行为。没有那么多代码要写:

    override public function initialize():void {
        addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);

        super.initialize();
    }

    private function addedToStageHandler(event:Event):void {
        if (skin == null) attachSkin();
    }

    private function removedFromStageHandler(event:Event):void {
        detachSkin();
    }

请注意,在SkinnableComponent类中,这两个事件侦听器在方法中附加(或不附加,取决于策略)commitProperties()。我将其移至initialize()方法中,因为我们不再需要检查skinDestructionPolicy属性的更改。

另请注意,如果确实设置mx::internal skinDestructionPolicy为并列,则此解决方案可能会导致错误"auto"

于 2012-01-07T16:50:19.623 回答