Sep 06

最近反复阅读kevincao的深入理解Flash的沙箱 – Application Domains 谈谈ActionScript垃圾回收

结合项目中遇到的一些问题,谈谈体会。

new ApplicationDomain();是新建系统域下子域。ApplicationDomain.currentDomain;是当前程序域。new ApplicationDomain(ApplicationDomain.currentDomain);是新建当前域下的子域。

如果不是用new ApplicationDomain(ApplicationDomain.currentDomain);加载的swf,就算用外部external-library-path方式用swc通过了编译,在使用时也是获得不到定义的。因为父域无法访问子域的定义。

但是kevincao说了。 如果子SWF文件是加载到主应用程序域里的,那么这个文件是不能卸载的(前提是子SWF文件内的类定义没有被主应用程序域里定义所覆盖)。如果子SWF文件是加载到子应用程序域内(Loader的默认方式),那么这个文件是一定能够被卸载的。

所以一般都是把加载的swf放到主应用程序域的子域。这时候,如果是用外部的load类来加载,那每个swf都有一个自己独立的子域。

而用getDefinition获得类必须知道你需要的swf的在哪个域里面,不然会找不到类定义。

可以在load类里面用可以用个关联数组储存当前加载swf的域。方便随时随处getDefinition。就不怕loader已经为null或销毁了。

非当前域getDefinition获得的Class,只能new给Object类型,不然会报错滴。比如这样。var spanishGreeter:Class = spanishGreeterLoader.getClass(“es/Greeter.swf”,”Greeter”);var greeter1:Object = new spanishGreeter();

之后你可以再AS为Sprite之类,但是只有为Object时,用greeter1.foo方式访问类里面的定义时才能通过编译,不然也是会报错滴。

一定要好好理解编译期和运行期的概念。

private var _loadDomain:Object = new Object();
public function load(lib:String):void
{
swfLib = lib;
request = new URLRequest(swfLib);
var context:LoaderContext = new LoaderContext();
// context.applicationDomain = ApplicationDomain.currentDomain;
context.applicationDomain = new ApplicationDomain();
_loadDomain[swfLib] = context.applicationDomain;
loader.load(request, context);
}

public function getClass(lib:String,className:String):Class
{
try
{
return _loadDomain[lib].getDefinition(className) as Class;
}
catch (e:Error)
{
throw new IllegalOperationError(className + " definition not found in " + swfLib);
}
return null;
}

written by panhezeng \\ tags:

©panhezeng for 阿潘道, 2006-2017. 原文地址:http://apsay.com/?p=1180
本文遵循署名-非商业性使用共享协议,转载请注明。

Leave a Reply