最近使用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,0,true);
_target.stage.invalidate();
} else {
_target.addEventListener(Event.ADDED_TO_STAGE,callLaterDispatcher,false,0,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,callLaterDispatcher,false,0,true);
_target.stage.invalidate();
return;
} else {
event.target.removeEventListener(Event.RENDER,callLaterDispatcher);
if (_target.stage == null) {
_target.addEventListener(Event.ADDED_TO_STAGE,callLaterDispatcher,false,0,true);
return;
}
}
inCallLaterPhase = true;
for (var method:Object in methods) {
method();
delete(methods[method]);
}
inCallLaterPhase = false;
}
public function get target():DisplayObject{
return _target;
}
}
}
分享到:
相关推荐
优化Flex应用性能的方法包括:代码优化(如避免冗余计算和减少对象创建)、资源管理(例如使用RSL和图像优化)、缓存策略(如利用本地存储)以及网络通信优化(如数据压缩和异步加载)。 ### 21. 如何设置默认值,...
Flex支持异步编程模型,如使用`AsyncToken`对象和`callLater()`方法,可以避免UI线程阻塞,确保等待界面的平滑显示。 5. **优化用户体验**: - **延迟显示**:不必要一开始就显示等待界面,只有当后台任务执行...
在IT领域,特别是针对Flash开发和ActionScript 3(AS3)编程的环境中,性能优化是确保应用程序流畅运行的关键。本文将深入探讨AS3性能调整的方法、原理以及实践中的注意事项,帮助开发者理解如何提高其应用的执行...
public function callLater(callback:function):void { // 某些异步操作完成后调用callback } callLater(function(event:Event):void { // 回调函数的实现 }); ``` 虽然这里没有明确声明接口,但`function(event:...
1. **用户界面**:使用AS3的`Sprite`和`TextField`等组件创建聊天界面,包括输入框、发送按钮和消息显示区域。了解如何动态更新UI是非常重要的。 2. **连接与断开**:使用`Socket.connect()`方法建立与服务器的连接...
这里,`callLater` 函数利用闭包,返回了一个匿名函数,该匿名函数能够访问外部函数`callLater`的参数。调用`callLater`并传入参数后,我们可以得到一个可以延迟执行的函数引用,并将这个引用传递给`setTimeout`: ...
TS实现的定时器/计时器,可自行翻译到其他语言 举例 翻译到C#后 long times = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long times_now = DateTimeOffset....callLater//下一帧 property: scale//时间缩放倍率
`reactor.callLater()`方法则可用于设定定时事件,让函数在未来某个时间点执行。 例如,以下代码展示了如何使用`reactor.callLater()`设置一个定时事件: ```python from twisted.internet import reactor def ...
JavaScript 闭包是一种强大的编程工具,常常被用来解决特定的问题和优化代码结构。在JavaScript中,闭包是指一个函数能够访问并操作其定义时的作用域内的变量,即使该函数在其外部作用域被调用。以下将详细介绍两个...
在更复杂的应用场景中,比如数据库查询或网络通信, Deferred 对象可以跨多个组件传递,每个组件都可以向其添加回调,这样就可以构建出一个完整的异步处理流程。例如,一个 SQL 查询的结果可能通过 Deferred 传递,...
在Twisted中,`Protocol`是定义网络通信行为的核心组件,它处理数据的接收和发送。例如,以下是一个简单的`Echo`协议示例: ```python from twisted.internet.protocol import Protocol from sys import stdout ...
wxPython是一个扩展了wxWidgets的Python封装库,它为Python提供了丰富的GUI组件。在使用wxPython开发GUI程序时,同样可以利用Python的threading模块来实现多线程功能,但需要特别注意线程安全问题。 线程安全是指在...
callLater(function() { console.log("Hello, world!"); }, 1000); ``` - **arguments对象**:在函数内部,`arguments`对象包含了所有传递给函数的参数,即使它们没有在函数签名中声明。 - **call和apply方法**...
reactor.callLater(1, counter) # 请求完成时的回调 def body_received(body): global req_done req_done += 1 def request_done(response): global req_made deferred = treq.json_content(response) req_...
对于异步操作,你可以使用`callLater`或`deferToThread`等Twisted的调度函数来处理消息的发送和接收。 txZMQ提供了一些高级接口,如`ZMQStream`,它允许开发者将ZeroMQ套接字与Twisted的I/O事件流相结合。这样,...
在Python的Twisted框架中,`Deferred`对象是异步编程的核心组件,它主要用于处理回调,使得开发者能够优雅地处理异步操作的结果。在Twisted这样的事件驱动网络库中,`Deferred`对象扮演着关键角色,因为它允许你注册...
在Python编程中,Twisted是一个事件驱动的网络编程框架,常用于编写异步代码。...在实际应用中,还应该对数据库进行适当的配置,以支撑高并发的场景,例如设置合适的连接数、使用合适的数据库引擎和索引优化等。
reactor.callLater(1, self.processHeadline, input) self.d.addCallback(self._toHTML) return self.d def printData(result): print(result) reactor.stop() def printError(failure): print(failure) ...