[转]跳桢

FlashPlayer10同步跳帧改进
本文探讨了FlashPlayer10对跳帧机制的改进,解决了FlashPlayer9中存在的异步跳帧问题,并讨论了这些变化对代码执行的影响。通过对比两个版本的差异,展示了这些改进如何帮助开发者更高效地进行编程。
[url]http://sban.biz/386[/url]

Flash Player 10更改了9的异步跳桢机制,这比开发者带来极大方便,利用这个改进,或许可以在AS3中实现阻塞编程。
1,Flash Player 9中的跳桢问题

Flash Player 9应当退出历史舞台了,余不待说,仅是异步跳桢这一个理由便充分了。在Flash Player 9中,以下代码将返回null:
// go to a specific frame where myDisplayObject is located
container.gotoAndStop ( 25 );
// output : null
trace( container.myDisplayObject );//该对象位于第25桢中
而在Flash Player 10中,它却可以返回实例。
2,另一个Flash Player 9的关于gotoAndStop的bug

设主场景中有一mc,此mc中有两桢,第二桢代码为:
trace(2)
主场景第一桢代码为:
mc.gotoAndStop(2);
毫无疑问,输出应该是:
2
然而实际却是:
2

2
这是Flash Player 9的一个bug,在Flash Player 10中不存在这个问题。
3,Flash Player 9与10的跳桢区别

Flash Player 9的跳桢是异步的,而10的跳桢却是同步的。
当gotoAndStop发生时:

[list]
[*]Flash Player 9 [*]Flash Player 10
[*]对比桢差异,移除所有非动态添加的、在新桢中不存在的对象,移动播放头 [*]对比桢差异,移除所有非动态添加的、在新桢中不存在的对象 [*]非动态:非代码添加
[*]执行gotoAndStop之后代码 [*]添加静态对象,执行桢代码,移动播放头
[*]… [*]执行gotoAndStop之后代码
[*] 在一代代码执行周期中,在enterFrame事件监听中,添加静态对象,执行桢代码 [*]
[/list]


4,Flash Player如何比对静态对象是否相同

1) 如果静态对象在新桢中没有新的关键桢,则一定保留
2) 如果静态对象在新桢中有新的关键桢,但该对象未与任何类关联,则保留,否则移除
5,两个版本跳桢的不同对桢周期的影响

在Flash Player一个完整的桢周期中,共做两件事情:执行代码与渲染,又细分为五小步:
1) Player事件调度 – 比如Timer事件,鼠标事件,ENTER_FRAME事件,URLLoader事件等等。

2) 用户代码执行 – 所有侦听上一步相应事件的代码被执行。
3) RENDER事件调度 – 在用户代码执行期间调用stage.invalidate()会触发这一特殊事件。
4) 最后的用户代码执行 – 侦听上述第三步特殊事件的用户代码此时被执行。
5) Player更改显示列表。
在第2小步时,在Flash Player 9中,包括执行桢代码,这是由对enterFrame监听引起的;而在Flash Player 10中,同样的桢代码是在第1小步内执行完成的。Flash Player 10对跳桢的改进有利于减少桢周期中代码执行的环节。
### Python 中栈帧逃逸的概念及解决方案 在 Python 中,栈帧逃逸(Stack Frame Escape)是一个与性能优化和内存管理相关的重要概念。虽然 Python 的实现细节与 Java 不同,但其核心思想是类似的:当一个对象或变量的作用域超出了局部方法的范围时,它可能会被其他方法或线程访问,这种现象可以类比为“逃逸”。 #### 栈帧逃逸的定义 在 Python 中,栈帧通常用于存储函数调用期间的局部变量、参数和其他上下文信息。如果一个局部对象或变量通过返回值、闭包或其他方式被外部作用域访问,则认为该对象或变量发生了“逃逸”。例如,当一个函数返回了一个内部创建的对象时,该对象的作用域就超出了原始栈帧的范围[^1]。 ```python def create_local_obj(): relic = TombRelic() # 局部对象 return relic.display() # 对象未逃逸 def create_escaped_obj(): return TombRelic() # 对象逃逸 ``` 在上述代码中,`create_local_obj` 函数中的 `relic` 对象仅在方法内部使用,因此不会发生逃逸;而 `create_escaped_obj` 函数返回了 `TombRelic` 实例,导致该对象逃逸到外部作用域[^3]。 #### 栈帧逃逸的影响 1. **性能开销**:如果一个对象发生逃逸,Python 解释器可能无法对其进行栈上分配优化(Stack Allocation Optimization),从而需要将其分配到堆上,增加内存管理和垃圾回收的负担。 2. **内存占用**:逃逸的对象通常会占据更多的内存空间,尤其是在大规模数据处理场景下。 3. **线程安全性**:如果逃逸的对象被多个线程共享,可能会引发线程安全问题,类似于 Java 中的线程逃逸[^4]。 #### 解决方案 为了减少栈帧逃逸带来的性能和内存问题,可以采取以下措施: 1. **限制对象作用域**: 尽量避免将局部对象直接暴露给外部作用域。可以通过封装对象的行为来限制其访问范围。例如: ```python class TombRelic: def display(self): print("展示墓室文物") def create_local_obj(): relic = TombRelic() relic.display() # 局部使用 return None # 避免返回对象 ``` 2. **使用生成器**: 如果需要返回一系列对象,可以考虑使用生成器代替直接返回列表。生成器可以在需要时逐步生成对象,减少内存占用。 ```python def generate_relics(): for i in range(1000): yield TombRelic() for relic in generate_relics(): relic.display() ``` 3. **利用闭包**: 在某些情况下,可以通过闭包隐藏对象的实现细节,避免直接暴露对象本身。 ```python def create_relic_display(): relic = TombRelic() return lambda: relic.display() display_func = create_relic_display() display_func() # 调用闭包函数 ``` 4. **优化垃圾回收**: 确保逃逸的对象能够及时被垃圾回收机制释放。可以通过显式地删除引用或使用弱引用(`weakref` 模块)来降低内存泄漏的风险。 ```python import weakref def create_weak_ref(): relic = TombRelic() return weakref.ref(relic) weak_relic = create_weak_ref() if weak_relic() is not None: weak_relic().display() ``` #### 总结 Python 中的栈帧逃逸问题虽然不如 Java 明确,但在性能敏感的应用场景中仍然值得关注。通过限制对象作用域、使用生成器、闭包以及优化垃圾回收等方式,可以有效减少逃逸带来的负面影响。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值