Apache flex Spark Skinnable组件SkinDestruction策略
作为尝试解决应用程序内存泄漏的一部分,我们发现对于每个Apache flex Spark Skinnable组件SkinDestruction策略,apache-flex,flex4,skin,flex-spark,destruction,Apache Flex,Flex4,Skin,Flex Spark,Destruction,作为尝试解决应用程序内存泄漏的一部分,我们发现对于每个SkinnableComponent,默认情况下skinDestructionPolicy设置为“从不” 这意味着当使用静态蒙皮部件时,蒙皮将永远保留在内存中。 此外,将永远不会触发主机组件中partRemoved()的重写。 因此,我们在partAdded()覆盖中添加的事件侦听器不会被删除,这实际上会导致视图和外观保留在内存中 在进行大量视图切换时,这是不可接受的 以下是我们目前如何解决这一问题的示例: public class View
SkinnableComponent
,默认情况下skinDestructionPolicy
设置为“从不”
这意味着当使用静态蒙皮部件时,蒙皮将永远保留在内存中。此外,将永远不会触发主机组件中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
方法来规避这种行为似乎有些奇怪。
关于这方面的文档也很少,所以任何想法都是非常受欢迎的
干杯根据我的经验,在Flex SDK中使用
mx::internal
名称空间通常意味着:“如果你知道你在做什么,你可以使用这个功能,而且我们(未来的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”
,则此解决方案可能会导致错误。遇到完全相同的问题。扫描Flex代码库以确定是否可以通过设置另一个(公共)属性来设置此属性,并在整个SDK中仅找到一个实例:ViewMenuItem(mobile)在内部将其skinDestructionPolicy
设置为“auto”
。因此,除了使用mx::internal
名称空间来设置该属性之外,似乎没有其他方法。