四种情况 from LoaderContext详解:
1.(父子)默认情况下loader的applicationDomain是子swf的applicationDomain的父。
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain)
2.(同域)子swf使用和父swf相同的applicationDomain。
context.applicationDomain = ApplicationDomain.currentDomain
3.(异域)system domain作为子SWF的父域。
context.applicationDomain = new ApplicationDomain()
4.(异域)其他域作为子swf的父域
比如context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain.parentDomain.parentDomain)
一、
LoaderContext详解里允许直接使用另一个类定义,是指通过自己的域获得类的定义,如ApplicationDomain.currentDomain.getDefinition 或 getDefinitionByName。
如果想直接像使用本项目的类那样定义对象,必须要在本项目中提供类的信息,AS3 load SWF:代码补全 。这种是父要直接使用子,需要同域载入。
二、
父SWF:
Parent.as
var a:A = new A; // 输出PA (可以只引用导入,而不实例化new,Child也能看到定义)
载入Child.swf
-----------------------------
A.as
构造函数 trace("PA")
子SWF:
Child.as
var a:A = new A;// 异域载入输出 CA, 同域、父子输出 PA。
-----------------------------
A.as
trace("CA")
如果都父子SWF都定义了类A,A的构造函数分别trace("PA") trace("CA"),并且在代码中都使用A生成了对象。
那么就取决于子SWF使用的applicationDomain 了。
按 父子或同域载入,子SWF中使用类A定义对象,由于与父SWF定义的A冲突,会直接使用父SWF对A的定义。
虽然不是通过getDefinitionByName动态定义,子SWF生成A对象的地方会输出"PA"了。
单独运行子SWF还是输出"子A"。所以说AS是脚本语言,是动态的,编译时连使用哪个类都没有确定下来。
三、
代码:
父SWF:
Parent.as
var a:A ; //这里分两种情况,有这句在Parent.swf中定义A,没有这句就是没在Parent.swf中定义A。
先载入Child1.swf
SWF1载入完毕发出complete事件后再载入Child2.swf
-----------------------------
A.as
构造函数 trace("PA")
子SWF1:
Child1.as
var a:A ;
-----------------------------
A.as
trace("CA1")
子SWF2:
Child2.as
var a:A = new A;
-----------------------------
A.as
trace("CA2")
三种情况:
1.
条件:
Parent.swf中定义A
无论何种方式载入Child1.swf
父子或同域载入Child2.swf
结果:
Child2.swf使用Parent.swf定义的A,输出PA。
2.
条件:
Parent.swf中不定义A
父子或异域载入Child1.swf
任何方式载入Child2.swf
结果:
Child2.swf使用自己定义的A,输出CA2。
3.
条件
Parent.swf中不定义A
同域载入Child1.swf(必须同域,父子域不行)
父子或同域载入Child2.swf
结果:
Child2.swf使用Child1.swf定义的A,输出CA1。
因为Paren和Child1同域,同域和父子域的区别就是同域父可以直接使用子的类定义。
所以在Parent.swf中通过ApplicationDomain.curentDomain.getDefinition("A")可以获得Child1所定义的A。
意味着Child2能通过ApplicationDomain.curentDomain.parentDomain.getDefinition("A")获得Child1所定义的A。
在发生冲突时Child2优先使用了父域中定义的A。当然如果Parent定义了A,就是第1点情况了,Child2.swf会使用Parent定义的A,而看不到Child1定义的A。
四、
如果父子SWF都定义了类A,并且子SWF 入口可运行文件的类 有个函数 setA(a:A)。
父SWF :
var a:A = new A;
loader.content.setA(a);
如果不是同域或父子,即使你在父子SWF中定义的两个A都是一样的,甚至是同一个项目 使用同一个类A 通过两个不同的可运行文件生成的两个SWF,子SWF中setA()函数也会如下报错:
TypeError: Error #1034: 强制转换类型失败:无法将 com.aaa.resource::A@1490c41 转换为 com.aaa.resource.A。
com.aaa.resource::A@1490c41是父SWF中类A的定义,com.aaa.resource.A是子SWF类A的定义。
所以如果在项目中你想要不经过序列化,直接在两个SWF传对象,那么你载入方式就必须采用同域或父子了。
然后针对那些 你不想在子SWF中使用 父SWF中定义的同名冲突类,只留下改名一条途径了。