1

我不想使用硬编码的 switch 语句,将类的字符串名称传递给它,然后实例化适当的类,我想将类的实际名称传递给我的工厂方法并让它动态创建一个实例那个班的。我认为这将是微不足道的,并且很惊讶它不起作用。我一定错过了一些非常基本的东西:

示例代码:

createProduct(50, "Product1Class");
createProduct(5, "Product2Class");


private function createProduct(amount:uint, productClassName:String):void {
    var productReference:Class;
    try {
        productReference = getDefinitionByName(productClassName) as Class;

        for (var i:uint = 0; i < amount; i++) {
        var product = new productReference() as ProductBaseClass; // throws reference error!
        }
    } catch (error:ReferenceError) {
        throw new ReferenceError(error.message + " Have you linked a library item to this class?");
    }
 }

唯一可能有点奇怪(不确定)的是这些“产品”实际上是链接库项目(即:我在库中有一个与 Product1Class 的链接和另一个与 Product2Class 的链接的movieClip,它们都扩展了 ProductBaseClass,这反过来又扩展了 MovieClip。

为什么引用错误?

4

3 回答 3

1

如果您有一个运行时加载的库,那么类不会编译到主 swf 中,因此当您尝试创建它们时会出现运行时引用错误。

要解决此问题,您可以声明要编译的类的“虚拟”变量,或者如果使用 flex 编译器,则可以选择包含您缺少的类。

例如,在您的项目中的任何地方声明这些

private var p1:Product1Class;
private var p2:Product2Class;

这是一个令人沮丧的问题,如果您的类扩展了作为动态类的 MovieClip,您可能可以通过执行以下操作来访问属性等:

var product:MovieClip = new productReference() as MovieClip;
p1["someCustomProperty"]; //Dot notation might work here as it is a dynamic class
于 2011-01-05T16:12:46.177 回答
1

getDefinitionByName() 和 ApplicationDomain.currentDomain.hasDefinition() 需要完全限定的类名。当 Product1Class 和 Product2Class 在默认包中时,原始帖子中的示例代码有效。但是,如果将产品类移动到另一个包,则必须确保向 getDefinitionByName() 提供完全限定的类名。

因此,如果我们将产品类放在 com.example.products 中,则调用变为:

productReference = getDefinitionByName("com.example.products.Product1Class") as Class;

我不太确定这种动态工厂类的最佳实践是什么,但我最终做的是(因为所有产品都在同一个包中)是在我的工厂类中创建一个常量,为我的定义包产品:

private const PRODUCT_PACKAGE:String = "com.example.products."; // note the trailing period

因此,您的客户端代码不需要知道(也不需要定义)产品包。使用 getDefinitionByName() 时,您只需将此常量添加到您的产品类名称中。

于 2011-01-09T03:17:08.267 回答
1

Chris 是绝对正确的,ReferenceError 实际上是在调用期间抛出的,这意味着反射方法在您的应用程序域中getDefinitionByName找不到Product1Class或。Product2Class您始终可以通过直接检查应用程序域来检查定义是否可用,例如:

// inside your createProduct method, yields 'false'.
ApplicationDomain.currentDomain.hasDefinition( productClassName );

这些库资产是在运行时加载的吗?如果是这样,您可以通过向您的加载器添加适当配置的方法来确保将库 swf 加载到当前应用程序域中LoaderContext,或者您可以将调用替换为getDefinitionByName加载的 swf 的应用程序域的getDefinition方法。

于 2011-01-06T05:57:49.503 回答