Flash 平台技术的优化(十四) 冻结和解冻对象

使用 REMOVED_FROM_STAGE 和 ADDED_TO_STAGE 事件正确冻结和解冻对象。
要优化您的代码,请始终冻结和解冻您的对象。冻结和解冻对所有对象都很重要,但对显示对象尤其重要。即使显示对象不再位于显示列表中并正在等待作为垃圾回收,其代码仍然占用大量 CPU。例如,它们仍然在使用 Event.ENTER_FRAME。因此,使用 Event.REMOVED_FROM_STAGE 和 Event.ADDED_TO_STAGE 事件正确冻结和解冻对象非常关键。以下示例显示一个在舞台上播放的、与键盘交互的影片剪辑:
// Listen to keyboard events
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyIsDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyIsUp);
// Create object to store key states
var keys:Dictionary = new Dictionary(true);
function keyIsDown(e:KeyboardEvent):void
{
// Remember that the key was pressed
keys[e.keyCode] = true;
if (e.keyCode==Keyboard.LEFT || e.keyCode==Keyboard.RIGHT)
{
runningBoy.play();
}
}
function keyIsUp(e:KeyboardEvent):void
{
// Remember that the key was released
keys[e.keyCode] = false;
for each (var value:Boolean in keys)
if ( value ) return;
runningBoy.stop();
}
runningBoy.addEventListener(Event.ENTER_FRAME, handleMovement);
runningBoy.stop();
var currentState:Number = runningBoy.scaleX;
var speed:Number = 15;
function handleMovement(e:Event):void
{
if (keys[Keyboard.RIGHT])
{
e.currentTarget.x += speed;
e.currentTarget.scaleX = currentState;
} else if (keys[Keyboard.LEFT])
{
e.currentTarget.x -= speed;
e.currentTarget.scaleX = -currentState;
}
}


单击“ 删除” 按钮后,将从显示列表中删除该影片剪辑:
// Show or remove running boy
showBtn.addEventListener (MouseEvent.CLICK,showIt);
removeBtn.addEventListener (MouseEvent.CLICK,removeIt);
function showIt (e:MouseEvent):void
{
addChild (runningBoy);
}
function removeIt(e:MouseEvent):void
{
if (contains(runningBoy)) removeChild(runningBoy);
}
即使将该影片剪辑从显示列表中删除,它仍会调度 Event.ENTER_FRAME 事件。影片剪辑仍在运行,但不会呈现。要正确处理
这种情况,请侦听正确的事件并删除事件侦听器,以阻止执行占用大量 CPU 资源的代码:
// Listen to Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE
runningBoy.addEventListener(Event.ADDED_TO_STAGE,activate);
runningBoy.addEventListener(Event.REMOVED_FROM_STAGE,deactivate);
function activate(e:Event):void
{
// Restart everything
e.currentTarget.addEventListener(Event.ENTER_FRAME,handleMovement);
}
function deactivate(e:Event):void
{
// Freeze the running boy - consumes fewer CPU resources when not shown
e.currentTarget.removeEventListener(Event.ENTER_FRAME,handleMovement);
e.currentTarget.stop();
}
按下“ 显示” 按钮后,将重新启动影片剪辑,它将再次侦听 Event.ENTER_FRAME 事件且键盘将正确控制该影片剪辑。

注: 如果将显示对象从显示列表中删除,则完成删除后将其引用设置为 null 不能确保该对象是冻结的。如果不运行垃圾回收器,则对象将继续占用内存和 CPU 处理,即使此对象不再显示。要确保对象占用的 CPU 处理最少,请确保在将其从显示列表中删除后完全将其冻结。
在 Flash Player 10 及更高版本中,如果播放头遇到一个空帧,将自动冻结显示对象,即使没有实施任何冻结行为也是如此。冻结的概念在使用 Loader 类加载远程内容时也很重要。在 Flash Player 9 中使用 Loader 类时,必须通过侦听由 LoaderInfo
对象调度的 Event.UNLOAD 事件来手动冻结内容。必须手动冻结每个对象,这是一项至关重要的任务。Flash Player 10 对Loader 类引入了一个重要的新方法,称为 unloadAndStop()。通过此方法,可以卸载 SWF 文件、自动冻结加载的 SWF 文件
中的每个对象并强制运行垃圾回收器。
以下代码将加载 SWF 文件,然后使用 unload() 方法将其卸载,这需要更多的处理操作和手动冻结:
var loader:Loader = new Loader();
loader.load ( new URLRequest ( "content.swf" ) );
addChild ( loader );
stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
function unloadSWF ( e:MouseEvent ):void
{
// Unload the SWF file with no automatic object deactivation
// All deactivation must be processed manually
loader.unload();
}
最好使用 unloadAndStop() 方法,该方法以本机方式处理冻结并强制运行垃圾回收过程:
var loader:Loader = new Loader();
loader.load ( new URLRequest ( "content.swf" ) );
addChild ( loader );
stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
function unloadSWF ( e:MouseEvent ):void
{
// Unload the SWF file with automatic object deactivation
// All deactivation is handled automatically
loader.unloadAndStop();
}
调用 unloadAndStop() 方法时将执行下列操作:
• 停止声音。
• 将删除注册到 SWF 文件的主时间轴中的侦听器。
• 停止 Timer 对象。
• 释放硬件外围设备(如摄像头和麦克风)。
• 停止每个影片剪辑。
• 停止调度 Event.ENTER_FRAME、Event.FRAME_CONSTRUCTED、Event.EXIT_FRAME、Event.ACTIVATE 和
Event.DEACTIVATE。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值