3

背景

我正在使用纯 Action Script 3 开发一个高度模块化的应用程序(我们使用 Flex 4 SDK 来自动化我们的构建,但我们所有的代码都必须能够直接在 Flash CS4 Professional 中编译)。

我们有一个“framework.swc”文件,其中包含在所有模块之间共享的接口定义,我们有一个加载其他模块的“mainmodule.swf”,然后我们有其他模块的各种 .swf 文件。我们使用 Loader 类,结合 ApplicationDomain::getDefinition() 动态加载类[我们使用“new LoaderContext(false,ApplicationDomain.currentDomain)”]。

问题

我们所有的模块都实现了在“framework.swc”中定义的“AbstractModule”接口。但是,当我实例化一个动态加载的模块时,(module is AbstractModule) 返回 false。更重要的是,如果我调用 module.someMethod(someobject),其中 someobject 实现了“framework.swc”中定义的接口,并且模块的方法需要“framework.swc”中定义的相同接口的对象,我会收到运行时错误“TypeError:错误 #1034:类型强制失败:无法将 _ 转换为 _。”

似乎“mainmodule.swf”和“loadedmodule.swf”(我一直在加载以进行测试的模块)在内部对“framework.swc”中的共享接口使用单独的定义

问题

如何使“mainmodule.swf”和“loadedmodule.swf”将它们的公共接口解析为共享定义,以便类转换和类比较正确成功?

4

4 回答 4

1

行。这不是最漂亮的解决方案,但它会起作用。基本上,对于每个接口“AbstractX”(用其他东西替换“X”),您需要创建两个包装类:“ImportX”和“ExportX”。ExportX 的目标是通过包装 AbstractX 成功地将 AbstractX 扩展为 Object 类型,提供与 AbstractX 类型相同的所有方法,但仅使用内置/预定义数据类型或在其签名中属于 flash 的数据类型。ImportX 的目标是缩小动态加载的对象,该对象具有与 AbstractX 类型相同的特征(但不能强制转换为 AbstractX 类型且不被识别为 AbstractX 类型),但属于 AbstractX 接口的 Object 类型。ExportX 和 ImportX 都使用 ImportY、ImportZ 等;但是,ExportX 使用 ImportY、ImportZ 等。包装参数,它委托给 AbstractX 类型的对象,而 ImportX 使用它们来包装返回值,这些返回值来自委托给 Object 类型的对象。为了使这更容易理解,我提供以下示例:

公共接口 AbstractX
{
    // 导出/导入函数是必需的
    // 对于所有此类接口。他们允许
    // 正确操作包装器。
    函数导出():对象;
    函数原始():对象;

    // 接口功能不同
    // 接口到接口。他们能
    // 被称为更合适的东西。
    函数接口Function1(参数:AbstractY):AbstractZ;
    函数接口Function2(参数:AbstractA):AbstractB;
}
// Import_ 类型的类总是实现 Abstract_
公共类 ImportX 实现 AbstractX
{
    // Import_ 对象的构造函数
    // 始终是 Object 类型。
    公共函数 ImportX(obj : Object) : void {
        _loadedobj = 对象;
        _exportobj = obj.export();
    }

    // 每个 Import_ 类都必须实现类似的“包装”功能:
    公共静态函数包装(obj:对象):AbstractX {
        变量结果:AbstractX = null;
        如果(对象!= null){
            if ( obj is AbstractX ){ // 如果可转换,则不直接换行。
                结果 = obj as AbstractX;
            }else if ( obj.original() is AbstractX ){ // 不要双重换行
                结果 = obj.original() as AbstractX;
            }别的{
                // 需要包装。
                结果 = 新 ImportX(obj);
            }
         }
         返回结果;
     }

    公共函数导出():对象{
        返回_exportobj;
    }

    公共函数原始():对象{
        返回_loadedobj;
    }

    // 对于接口函数,我们委托给 _exportobj
    // 我们包装返回值,但不包装参数。
    公共函数interfaceFunction1(参数:AbstractY):AbstractZ {
        返回 AbstractZ.wrap(_exportobj.interfaceFunction1(param));
    }

    公共函数interfaceFunction2(参数:AbstractA):AbstractB {
        返回 AbstractB.wrap(_exportobj.interfaceFunction2(param));
    }

    私有变量_loadedobj:对象;
    私有变量 _exportobj :对象;
}
// 虽然 Export_ 对象提供了类似的方法来键入 Abstract_,
// 需要更改签名,以便只有内置/预定义类型
// 出现。因此 Export_ 从不实现 Abstract_。
公共类ExportX
{
    // Export_ 的构造函数总是采用 Abstract_ 类型的对象
    公共函数ExportX(obj:AbstractX):无效{
        _obj = 对象;
    }

    公共函数原始():对象{
        返回_obj;
    }

    公共函数导出():对象{
        返回这个;
    }

    // 对于接口函数,我们委托给 _obj
    // 我们包装参数,而不是返回值。
    // 还要注意签名的变化。
    公共函数interfaceFunction1(参数:对象):对象{
        return _obj.interfaceFunction1(AbstractY.wrap(param));
    }

    公共函数interfaceFunction2(参数:对象):对象{
        return _obj.interfaceFunction2(AbstractA.wrap(param));
    }

    私有变量_obj:AbstractX = null;
}
// X 类的定义可以出现在任何模块中并被任何模块加载。
公共类 X 实现 AbstractX
{
    公共函数 X( /* ... */ ) : void {
        //...
    }

    公共函数导出():对象{
        如果(!_export){
            _export = new ExportX(this);
        }
        返回_出口;
    }

    公共函数原始():对象{
        返回这个;
    }

    公共函数interfaceFunction1(参数:AbstractY):AbstractZ {
        // ...
    }

    公共函数interfaceFunction2(参数:AbstractA):AbstractB {
       // ...
    }

    私有 var _export : 对象 = null;
}
// 行。所以这就是你如何使用它......
var classx : Class = dynamicLoadClassFromModule("X","module.swf");
var untypedx : Object = new classx();
var typedx : AbstractX = ImportX.wrap(untypedx);
// 使用 typedx ...
于 2009-07-19T03:09:54.620 回答
0

您应该-compiler.external-library-path按照此处记录的方式尝试...这样,您可以构建一个依赖于接口的 swc,该接口不在其中,而是来自另一个接口,从而避免冲突...不知道如何在 CS4 中做到这一点尽管 ...

问候

back2dos

于 2009-07-11T01:58:33.993 回答
0

您可能想要使用运行时共享库​​ (RSL)。RSL 允许您进行动态链接。但是,我不知道 CS4 是否可以构建这些。也许您可以重新考虑“必须能够直接在 Flash CS4 中编译”的要求,或者考虑通过 CS4 IDE 中的宏/脚本使用 Flex SDK 进行编译。

如果这绝对不是一种选择,另一种方法是在模块之间建立更松散的耦合,并更多地依赖于模块 SWF 的隐含公共外部接口,而不是代码级集成。

于 2009-07-11T09:17:15.917 回答
0

我不能 100% 确定它是否是您需要的,但Gaia 框架实现了一个全局 API,由许多 swf 共享以相互交互。你可以检查一下,也许会得到一些想法。现在我面临的情况与您的情况非常相似,所以我正在检查替代方案......这篇文章将非常有用,谢谢!

于 2009-07-20T11:42:41.047 回答