加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flash & Flex组件优化的杀手锏callLater

发布时间:2020-12-15 18:22:49 所属栏目:百科 来源:网络整理
导读:最近使用flexlib,看源码的时候发现有大量的 calllater() 方法,搜了搜 原来如此: ? 原帖:http://www.colorhook.com/blog/?p=216 ? Flash的fl组件和Flex的mx组件都有一个受保护方法callLater,callLater可以说是优化组件执行效率的一个杀手锏,极其有用。

最近使用flexlib,看源码的时候发现有大量的 calllater() 方法,搜了搜 原来如此:

?

原帖:http://www.colorhook.com/blog/?p=216

?

Flash的fl组件和Flex的mx组件都有一个受保护方法callLater,callLater可以说是优化组件执行效率的一个杀手锏,极其有用。 拿Flash的fl组件为例,fl组件有个重绘方法redraw(),如果改变组件的大小,焦点的获得和丢失都会是组件重绘来呈现不同的状态。而组件是复杂的,重绘的开销很大。如果假想一个按钮执行以下程式来更改外观,并且每次的更改都触发redraw()方法执行,那它将执行3次重绘,很显然是不须要的。 button.width=200; button.height=28; button.setStyle("textFormat",myTextFormat); 一个优化的方式是假设组件不会自动重绘,需要手动进行: button.width=200; button.height=28; button.setStyle("textFormat",myTextFormat); button.redraw(); 这个方式不太友好,每次都要记得去重绘组件,幸运的是callLater解决了这个问题。 callLater把要执行的函数延迟到下一帧。所以对button的width更改后,它会记得在下一帧重绘自身,当然这一帧你还改变了height和样式,它也只是重复地记忆要在下一帧重绘自身。到了下一帧的时候,它执行一次redraw(),仅是一次。 Flex组件的基类UIComponent有110多个公开属性,90个公开方法,17个受保护方法,70多个事件,10多个样式,10多个效果,还有6个常量。一个基类都如此庞大,可想而知,优化是多么重要。 在Flex组件的callLater中,重绘被分割成了三个受保护的方法: # commitProperties() # measure() # updateDisplayList() 职责的分割更加提高了效率,这些延迟执行都是callLater实现的。把callLater实现的细节抽取下来写成一个单独的类: package com.colorhook.tools{ ? ??? /** ??? ?*??? @author colorhook ??? ?* @copyright http://www.colorhook.com ??? ?*/ ? ??? ?import flash.display.DisplayObject; ??? ?import flash.utils.Dictionary; ??? ?import flash.events.Event; ? ??? public class FrameCallLater implements ICallLater{ ? ??? ??? private var _target:DisplayObject; ??? ??? private var methods:Dictionary; ??? ??? private var inCallLaterPhase:Boolean=false; ? ??? ??? public function FrameCallLater(target:DisplayObject){ ??? ??? ??? this._target=target; ??? ??? ??? methods=new Dictionary(true); ??? ??? ??? super(); ??? ??? } ? ??? ??? /** ??? ??? ?* defined by ICallLater,I write a class TimeCallLater to implement it also. ??? ??? ?*/ ??? ??? public function call(fun:Function):void{ ??? ??? ??? if (inCallLaterPhase||_target==null) { return; } ? ??? ??? ??? methods[fun]=true; ? ??? ??? ??? if (_target.stage != null) { ??? ??? ??? ??? _target.stage.addEventListener(Event.RENDER,callLaterDispatcher,false,true); ??? ??? ??? ??? _target.stage.invalidate(); ??? ??? ??? } else { ??? ??? ??? ??? _target.addEventListener(Event.ADDED_TO_STAGE,true); ??? ??? ??? } ??? ??? } ? ??? ??? private function callLaterDispatcher(event:Event):void { ??? ??? ??? if (event.type == Event.ADDED_TO_STAGE) { ??? ??? ??? ??? _target.removeEventListener(Event.ADDED_TO_STAGE,callLaterDispatcher); ??? ??? ??? ??? _target.stage.addEventListener(Event.RENDER,true); ??? ??? ??? ??? _target.stage.invalidate(); ??? ??? ??? ??? return; ??? ??? ??? } else { ??? ??? ??? ??? event.target.removeEventListener(Event.RENDER,callLaterDispatcher); ??? ??? ??? ??? if (_target.stage == null) { ??? ??? ??? ??? ??? _target.addEventListener(Event.ADDED_TO_STAGE,true); ??? ??? ??? ??? ??? return; ??? ??? ??? ??? } ??? ??? ??? } ? ??? ??? ??? inCallLaterPhase = true; ? ??? ??? ??? for (var method:Object in methods) { ??? ??? ??? ??? method(); ??? ??? ??? ??? delete(methods[method]); ??? ??? ??? } ??? ??? ??? inCallLaterPhase = false; ??? ??? } ? ??? ??? public function get target():DisplayObject{ ??? ??? ??? return _target; ??? ??? } ? ??? } }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读