Module的域问题:无法将类A转换成类A?

  • 本站文章除注明转载外,均为本站原创或者翻译。
  • 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商;
  • 本站部分原创和翻译文章提供markdown格式源码,欢迎使用文章源码进行转载;
  • 本博客采用 WPCMD 维护;
  • 本文标题:Module的域问题:无法将类A转换成类A?
  • 本文链接:http://zengrong.net/post/517.htm

程序框架是这样的一个结构:

其中Root就是Application,Window和Widget都是Module。Window由Application载入,而Widget由Window载入。

部分的代码片段:

private static const STATUS_WIDGET:String = 'widget/status/view/components/StatusWidget.swf';
public function loadr():void
{
    _statusMI = ModuleManager.getModule(STATUS_WIDGET); 
    _statusMI.addEventListener(ModuleEvent.READY, _statusReady);
    _statusMI.load();
}
private function _statusReady(evt:ModuleEvent):void
{
    //此句出错
    _statusM = StatusWidget((evt.target as IModuleInfo).factory.create());
    _statusM.setParent(mediator);               
    top.addChild(_statusM);
}

就在我要将由Window载入的Module转换成Widget的相关类时(注释下方代码),奇怪的事情出现了:

TypeError: Error #1034: 强制转换类型失败:无法将
widget.info.view.components::StatusWidget@18ebc29 转换为
widget.info.view.components.StatusWidget

还有这等事?不能将自己转换成自己?

略一思考,想起Flex帮助中关于Module域(Module domains)的介绍,找到之后翻了一下,这段话解释了原因:

Because a module is loaded into a child domain, it owns class
definitions that are not in the main application’s domain. For
example, the first module to load the PopUpManager class becomes the
owner of the PopUpManager class for the entire application because it
registers the manager with the SingletonManager. If another module
later tries to use the PopUpManager, Adobe ® Flash® Player throws an
exception.

同时提供了解决方法:

The solution is to ensure that managers such as PopUpManager and
DragManager and any other shared services are defined by the main
application (or loaded late into the shell’s application domain). When
you promote one of those classes to the shell, the class can then be
used by all modules. Typically, this is done by adding the following
to a script block:

import mx.managers.PopUpManager;
import mx.managers.DragManager;
private var popUpManager:PopUpManager;
private var dragManager:DragManager;

简单的说,这种情况是由于主文件的域与子文件的域相对独立,对于同一个类,会分别进行载入,这就造成了在比较时,两个类并不相同。解决的办法,就是在主文件中,先对这个类进行一次引用。例如,我在Root.mxml中加入这段代码,程序就没问题了:

import mx.modules.ModuleManager;
import mx.modules.Module;
import widget.status.view.components.StatusWidget;

private var _moduleManager:ModuleManager;
private var _module:Module;
private var _status:StatusWidget;