Spark SkinnableComponent skinDestructionPolicy [英] Spark SkinnableComponent skinDestructionPolicy

查看:94
本文介绍了Spark SkinnableComponent skinDestructionPolicy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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

但是,使用mx::internal方式来规避此行为对我来说似乎很奇怪. 与此相关的文档也很稀少,因此任何想法都将受到欢迎.

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.

欢呼

推荐答案

以我的经验,在Flex SDK中使用mx::internal命名空间通常意味着:使用此功能(如果您知道自己在做什么),并且我们(Adobe或将来的Apache社区)也不保证该API在以后的Flex版本中永远不会更改."

In my experience the usage of the mx::internal namespace in the Flex SDK usually means something along the lines of: "you can use this functionality, if you know what you're doing, and also we (Adobe, or the Apache community in the future) don't guarantee that this API will never change in future versions of Flex".

因此,除非您非常关心向后兼容性,否则它的用法没有真正的问题.如果确实要避免使用它,则始终可以在子类中仅实现skinDestructionPolicy="auto"的行为.没有太多要编写的代码:

So there's no real issue with its usage, unless you're very concerned with backwards compatibility. If you really want to avoid using it, you can always just implement the behavior of skinDestructionPolicy="auto" in your subclass. There's not that much code to write:

    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属性中的更改.

Note that in the SkinnableComponent class these two event listeners are attached (or not, depending on the policy) in the commitProperties() method. I moved that to the initialize() method because we don't need to check for changes in the skinDestructionPolicy property anymore.

还请注意,如果同时 did mx::internal skinDestructionPolicy设置为"auto",则此解决方案可能会导致错误.

Also note that this solution might cause an error if one did set mx::internal skinDestructionPolicy to "auto" alongside.

这篇关于Spark SkinnableComponent skinDestructionPolicy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆