IE播放Flash时引起"内存不能读"问题
我做的swf在Firefox里能正常,在ie + flashplayer debug version 也能播,但是在 ie + flashplayer non-debug version 里播放一段时间后就会出现 “该内存不能为 read”的错误。
痛骂Adobe,不同版本的flashplayer行为并不是完全相同的。不靠普。
因为整个系统比较大,一片一片剥离开查,花了整整两天时间。
并非某处抛异常,因为在非debug版异常会被简单忽略。
并非内存泄露,因为根据检测结果不到200M就死。
并非第归导致栈溢出,因为栈溢出会是一个渐进的过程,这中间画面会严重的停顿,并且在不同浏览器见不回有行为差异。
最终定位在一段复制 DisplayObject的程序上。 作了个简单的例子,在IE上点击七八下就死掉了。有兴趣的朋友可以实验一下。
package {
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.text.TextField;
public class TestProjcet extends Sprite
{
var Y:int = 0;
var tf:TextField ;
public function TestProjcet()
{
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
loader.load(new URLRequest("s2_raft.swf"));
stage.addEventListener(MouseEvent.MOUSE_DOWN,onDown);
}
private var mc:MovieClip;
private var mc2:MovieClip;
private var mc3:MovieClip;
private function onComplete(evt:Event):void{
mc = (LoaderInfo(evt.target).content) as MovieClip;
mc.scaleX = mc.scaleY = 0.2;
mc.y = Y;
this.addChild(mc);
mc2 = this.duplicateDisplayObject(mc) as MovieClip;
mc2.x = 200;
mc2.y = Y;
this.addChild(mc2);
mc3 = this.duplicateDisplayObject(mc) as MovieClip;
mc3.x = 400;
mc3.y = Y;
this.addChild(mc3);
}
private function onDown(evt:Event):void{
Y += 5;
this.removeChild(mc);
this.removeChild(mc2);
this.removeChild(mc3);
mc = null;
mc2 = null;
mc3 = null;
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
loader.load(new URLRequest("s2_raft.swf"));
}
private function duplicateDisplayObject(target:DisplayObject, autoAdd:Boolean = false):DisplayObject {
var targetClass:Class = Object(target).constructor;
var duplicate:DisplayObject = new targetClass() as DisplayObject;
// duplicate properties
duplicate.transform = target.transform;
duplicate.filters = target.filters;
duplicate.cacheAsBitmap = target.cacheAsBitmap;
duplicate.opaqueBackground = target.opaqueBackground;
if (target.scale9Grid) {
var rect:Rectangle = target.scale9Grid;
// Flash 9 bug where returned scale9Grid is 20x larger than assigned
rect.x /= 20, rect.y /= 20, rect.width /= 20, rect.height /= 20;
duplicate.scale9Grid = rect;
}
// add to target parent's display list
// if autoAdd was provided as true
if (autoAdd && target.parent) {
target.parent.addChild(duplicate);
}
return duplicate;
}
}
}