Apache flex 为什么updateDisplayList在Flex中停止出现?

Apache flex 为什么updateDisplayList在Flex中停止出现?,apache-flex,Apache Flex,奖励:已领取 概述:给出问题的代码部署在这里: 我遇到的问题是,某些操作序列(我不完全理解如何或为什么)导致我对invalidateDisplayList的调用无法生成对updateDisplayList的后续调用。我所知道的是,在此期间,其他一些视觉效果将无法出现(例如更改组件的宽度或添加新的子对象) 示例:下面的程序绘制了两列水平线。左侧的列在commitProperties期间绘制,右侧的列在updateDisplayList期间绘制。某个操作序列可能会导致右列停止更新 要触发此错误:首先

奖励:已领取

概述:给出问题的代码部署在这里:

我遇到的问题是,某些操作序列(我不完全理解如何或为什么)导致我对invalidateDisplayList的调用无法生成对updateDisplayList的后续调用。我所知道的是,在此期间,其他一些视觉效果将无法出现(例如更改组件的宽度或添加新的子对象)

示例:下面的程序绘制了两列水平线。左侧的列在commitProperties期间绘制,右侧的列在updateDisplayList期间绘制。某个操作序列可能会导致右列停止更新

要触发此错误:首先添加一个新项。现在点击开始按钮,一个条开始填满。如果按“添加行”按钮,右侧列和填充栏都将停止增长。左列继续不受约束。在TEComputeRow.tick()中的if语句的最后一行没有对帧执行之前,额外的组件不会出现。单击stop按钮停止TEComputeRow.tick()中if语句内的块的执行,一切都会恢复正常

问题:这里发生了什么

我可以通过使用validate now强制它执行操作,但它并不能解决问题,它只是为了一个框架而掩盖它。这看起来也是一个非常草率的黑客行为。有没有比使用validateNow更好的方法来处理updateDisplayList的丢失?有没有办法准确地确定世界的状况

MastersOfTime.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    backgroundColor="white"
    backgroundGradientAlphas="[1,1]"
    initialize="init()"
    enterFrame="tick()"
    creationComplete="addComputeArray()">
    <mx:Script>
        <![CDATA[
            import mx.containers.HBox;
            import mx.controls.Button;
            import mx.containers.VBox;
            import flash.utils.getTimer;
            private var global:int = 0;

            private function addComputeArray():void
            {
                var addButton:Button = new Button;
                addButton.label = "Add Row Item";
                addButton.addEventListener(MouseEvent.CLICK, addComputeBox);
                box.addChild(addButton);
            }

            private function addComputeBox(a:* = null):void
            {
                box.addChild(new TEComputeRow());
            }

            private function init():void
            {
                box.clipContent = false;
                box.graphics.lineStyle(1);
            }

            private function tick():void
            {
                global++;
                this.invalidateDisplayList();
                this.invalidateProperties();
                //this.validateNow();
            }
            protected override function commitProperties():void
            {
                super.commitProperties();
                box.graphics.moveTo(100, (global*3)%800);
                box.graphics.lineTo(200, (global*3)%800);
            }
            protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
            {
                super.updateDisplayList(unscaledWidth, unscaledHeight);
                box.graphics.moveTo(200, (global*3)%800);
                box.graphics.lineTo(300, (global*3)%800);
            }
        ]]>
    </mx:Script>
    <mx:VBox id="box"/>
</mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
    height="60"
    width="352"
    verticalGap="0"
    borderStyle="solid"
    enterFrame="tick()">
    <mx:Script>
        <![CDATA[
            public var doStuff:Boolean = false;
            private var parameter:Number = 0;

            private function tick(e:Event = null):void
            {
                var value:*;
                if(doStuff)
                {
                    parameter = parameter+1;

                    value = parameter;

                    fill.width = value;
                }
            }
        ]]>
    </mx:Script>
    <mx:Button label="turn on" click="{doStuff = true;}" height="20"/>
    <mx:Container id="fill" x="7" width="0" height="20" backgroundColor="0x8888AA"/>
    <mx:Button label="turn off" click="{doStuff = false;}" height="20"/>
</mx:VBox>

TEComputeRow.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    backgroundColor="white"
    backgroundGradientAlphas="[1,1]"
    initialize="init()"
    enterFrame="tick()"
    creationComplete="addComputeArray()">
    <mx:Script>
        <![CDATA[
            import mx.containers.HBox;
            import mx.controls.Button;
            import mx.containers.VBox;
            import flash.utils.getTimer;
            private var global:int = 0;

            private function addComputeArray():void
            {
                var addButton:Button = new Button;
                addButton.label = "Add Row Item";
                addButton.addEventListener(MouseEvent.CLICK, addComputeBox);
                box.addChild(addButton);
            }

            private function addComputeBox(a:* = null):void
            {
                box.addChild(new TEComputeRow());
            }

            private function init():void
            {
                box.clipContent = false;
                box.graphics.lineStyle(1);
            }

            private function tick():void
            {
                global++;
                this.invalidateDisplayList();
                this.invalidateProperties();
                //this.validateNow();
            }
            protected override function commitProperties():void
            {
                super.commitProperties();
                box.graphics.moveTo(100, (global*3)%800);
                box.graphics.lineTo(200, (global*3)%800);
            }
            protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
            {
                super.updateDisplayList(unscaledWidth, unscaledHeight);
                box.graphics.moveTo(200, (global*3)%800);
                box.graphics.lineTo(300, (global*3)%800);
            }
        ]]>
    </mx:Script>
    <mx:VBox id="box"/>
</mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
    height="60"
    width="352"
    verticalGap="0"
    borderStyle="solid"
    enterFrame="tick()">
    <mx:Script>
        <![CDATA[
            public var doStuff:Boolean = false;
            private var parameter:Number = 0;

            private function tick(e:Event = null):void
            {
                var value:*;
                if(doStuff)
                {
                    parameter = parameter+1;

                    value = parameter;

                    fill.width = value;
                }
            }
        ]]>
    </mx:Script>
    <mx:Button label="turn on" click="{doStuff = true;}" height="20"/>
    <mx:Container id="fill" x="7" width="0" height="20" backgroundColor="0x8888AA"/>
    <mx:Button label="turn off" click="{doStuff = false;}" height="20"/>
</mx:VBox>

首先,你正在可怕地滥用Flex生命周期,做一些你不该做的事情。。。更改行刻度中填充的宽度将启动另一个立即跳出的无效循环。如果你通过定时器而不是在enterFrame上驱动,你会马上变得更好

我的猜测是,您在每帧中花费了太多的时间重新使属性无效(更改宽度将使属性无效),因此播放器永远不适合更新显示列表


阅读、和Flex 3生命周期。

首先,你正在可怕地滥用Flex生命周期,做你不该做的事情。。。更改行刻度中填充的宽度将启动另一个立即跳出的无效循环。如果你通过定时器而不是在enterFrame上驱动,你会马上变得更好

我的猜测是,您在每帧中花费了太多的时间重新使属性无效(更改宽度将使属性无效),因此播放器永远不适合更新显示列表


阅读、和Flex 3生命周期。

使用.width是触发此问题的原因。如果将.width替换为.setActualSize,则问题停止。这些代码段在单独的路径中运行,.width和.height显然有能力跳过帧周期的一部分(updateDisplayList部分)。

使用.width是触发此问题的原因。如果将.width替换为.setActualSize,则问题停止。这些代码在单独的路径中运行,.width和.height显然有能力跳过帧周期的一部分(updateDisplayList部分)。

我将详细介绍Gregor的主要答案,说这是最适合您的阅读:您需要查看updateDisplayList()和commitProperties()作为需要/标记时从systemManager调用的函数。一个很好的例子(我认为在文章中)是,当你10 visible=true时会发生什么;20可见=假;30转到10;一帧500次(请原谅意大利面伪码)?在阅读了这个答案中的文章后,你会感觉好多了。我正在阅读建议阅读的内容,应该有机会在下周试用。Gregor,你给出的答案帮助我找到了正确的答案。请随时发送电子邮件给我public@johnuckele.com. 请同时在这里留言确认。不要担心报酬。我怀疑你是否想把它运到爱尔兰;)我将详细介绍Gregor的主要答案,说这是一本非常适合您的书:您需要将updateDisplayList()和commitProperties()视为在需要/标记时从systemManager调用的函数。一个很好的例子(我认为在文章中)是,当你10 visible=true时会发生什么;20可见=假;30转到10;一帧500次(请原谅意大利面伪码)?在阅读了这个答案中的文章后,你会感觉好多了。我正在阅读建议阅读的内容,应该有机会在下周试用。Gregor,你给出的答案帮助我找到了正确的答案。请随时发送电子邮件给我public@johnuckele.com. 请同时在这里留言确认。不要担心报酬。我怀疑你是否想把它运到爱尔兰;)