Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 正确使用getDefinitionByName_Actionscript 3 - Fatal编程技术网

Actionscript 3 正确使用getDefinitionByName

Actionscript 3 正确使用getDefinitionByName,actionscript-3,Actionscript 3,这是我的代码行: new (getDefinitionByName(String( "mypackage.MyDynamicClass" )) as Class) ; 这将生成一个错误:未定义mypackage.MyDynamicClass 我通过谷歌搜索找到了一个解决方案:在import语句中使用类名 所以 成功了 但是,我对这个解决方案并不满意,因为它实际上违背了动态类的好处。如果我知道导入中类的名称,那么为什么要将其用作字符串 有没有其他方法可以让类的动态加载工作 Vishwas它

这是我的代码行:

  new (getDefinitionByName(String( "mypackage.MyDynamicClass"  )) as Class) ;
这将生成一个错误:未定义mypackage.MyDynamicClass

我通过谷歌搜索找到了一个解决方案:在import语句中使用类名

所以

成功了

但是,我对这个解决方案并不满意,因为它实际上违背了动态类的好处。如果我知道导入中类的名称,那么为什么要将其用作字符串

有没有其他方法可以让类的动态加载工作


Vishwas

它绝对不会违反类的动态加载,因为我们的编译器在我们的项目中检测未使用的类/导入语句,然后将这些类文件打包为swc或swf,这样我们最终输出文件大小的优势可以减少

除非几次无法减少文件大小

在确保该类在IncludeClass.as中可用之前,您可能已经知道要通过getDefinitionByName加载的类是什么

为了更好的方式,您可以为您的项目导入语句

package
{
    public class IncludeClasses
    {
        import com.abc.db.Database; Database;
        import com.abc.RemoteLogTarget; RemoteLogTarget;
        import com.abc.LocalLogTarget; LocalLogTarget;
        import com.abc.exception.GlobalExceptionHandler; GlobalExceptionHandler;
        import com.abc.utils.NetConnectionMonitor; NetConnectionMonitor;
    }
}

您仍然想更好地使用您的方式,您可以尝试使用编译器选项。

这绝对不会违反类的动态加载,因为我们的编译器在我们的项目中检测未使用的类/导入语句,然后将这些类文件丢弃,打包为swc或swf,这样最终输出文件大小的优势可以减少

除非几次无法减少文件大小

在确保该类在IncludeClass.as中可用之前,您可能已经知道要通过getDefinitionByName加载的类是什么

为了更好的方式,您可以为您的项目导入语句

package
{
    public class IncludeClasses
    {
        import com.abc.db.Database; Database;
        import com.abc.RemoteLogTarget; RemoteLogTarget;
        import com.abc.LocalLogTarget; LocalLogTarget;
        import com.abc.exception.GlobalExceptionHandler; GlobalExceptionHandler;
        import com.abc.utils.NetConnectionMonitor; NetConnectionMonitor;
    }
}

如果您想更好地使用自己的方式,可以尝试使用编译器选项。

看看这篇文章: 您无法避免在运行时包含所需的类。您始终可以使用:

import mypackage.*

请注意,在包中包含所有类可能会增加代码大小。

请阅读本文: 您无法避免在运行时包含所需的类。您始终可以使用:

import mypackage.*

请注意,在包中包含所有类可能会增加代码大小。

我建议您使用抽象工厂 这是一种非常灵活的方法,可以在不知道要实例化哪个类的情况下创建对象

在这个抽象工厂类中,您将需要导入所有可能创建对象的类别,这不需要您导入主类中的所有类别,但您仍然需要导入抽象工厂和接口以与新对象通信

下面是一个简单的例子:

/*
The interface you will use to communicate with your objects
*/
InterfaceForAllMyClasses.as
public interface InterfaceForAllMyClasses
{
    public function callMe();
    public function callMe2();
}

/*
Your Classes wich implement the interface
*/
Class1.as
import mypackage.InterfaceForAllMyClasses;
public class Class1 implements InterfaceForAllMyClasses
{
    public function callMe() { trace("called Class1"); }
    public function callMe2() { trace("called Class1 too"); }
}

Class2.as
import mypackage.InterfaceForAllMyClasses;
public class Class1 implements InterfaceForAllMyClasses
{
    public function callMe() { trace("called Class2"); }
    public function callMe2() { trace("called Class2 too"); }
}

/*
The Abstract Factory
*/
AbstractFactory.as
import mypackage.InterfaceForAllMyClasses;
public class AbstractFactory
{
    public function giveMeObject(classNumber:Number):InterfaceForAllMyClasses
    {
        switch(classNumber)
        {
            case 0: return(new Class1()); break;
            case 1: return(new Class2()); break;
            // for any new class that you add you must add a case entry here
        }
    }
}

/*
Your Program
*/
import mypackage.InterfaceForAllMyClasses;
import mypackage.AbstractFactory;
MyProgram.as
public class MyProgram
{
    var abstractFactory:AbstractFactory = new AbstractFactory();

    public function main()
    {
        var x:InterfaceForAllMyClasses=AbstractFactory.giveMeObject(0);
        var y:InterfaceForAllMyClasses=AbstractFactory.giveMeObject(1);

        x.callMe();
        x.callMe2();
        y.callMe();
        y.callMe2();        
    }
}
如果无法从主应用程序导入类,因为它们在外部模块SWF中声明,则可以将每个模块作为抽象工厂,例如:

Interfaces/IModuleInterface.as

package Interfaces
    {
        public interface IModuleInterface
        {
            function giveMeObject(classNumber:Number):IObjectInterface;
        }
    }

Interfaces/IObjectInterface.as

package Interfaces
    {
        public interface IObjectInterface
        {
            function callMe():void;
            function callMeToo():void;
        }
    }

Modules/ModuleOne.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"         implements="Interfaces.IModuleInterface">
        <fx:Script>
            <![CDATA[
                import Interfaces.IObjectInterface;
                public function giveMeObject(classNumber:Number):IObjectInterface
                {
                    switch(classNumber)
                    {
                        case 1:
                            trace("ModuleOne: Instantiating 1");
                            return(new ModuleOneClassOne()); 
                            break;
                        case 2:
                            trace("ModuleOne: Instantiating 2");
                            return(new ModuleOneClassTwo()); 
                            break;
                    }
                    return(null);
                }
            ]]>
        </fx:Script>
        <fx:Declarations>
            <!-- Place non-visual elements (e.g., services, value objects) here -->
        </fx:Declarations>
        <s:Label x="10" y="10" text="Module One Loaded"/>
    </s:Module>

Modules/ModuleOneClassOne.as

    package Modules
    {
        import Interfaces.IObjectInterface;

        public class ModuleOneClassOne implements IObjectInterface
        {
            public function ModuleOneClassOne()
            {
                trace("ModuleOneClassOne: Instantiated");
            }

            public function callMe():void
            {
                trace("ModuleOneClassOne: called callMe()");
            }

            public function callMeToo():void
            {
                trace("ModuleOneClassOne: called callMeToo()");
            }
        }
    }

Modules/ModuleOneClassTwo.as

    package Modules
    {
        import Interfaces.IObjectInterface;

        public class ModuleOneClassTwo implements IObjectInterface
        {
            public function ModuleOneClassTwo()
            {
                trace("ModuleOneClassTwo: Instantiated");
            }

            public function callMe():void
            {
                trace("ModuleOneClassTwo: called callMe()");
            }

            public function callMeToo():void
            {
                trace("ModuleOneClassTwo: called callMeToo()");
            }
        }
    }

AbstractFactoryInModules.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   width="345" height="200">

        <fx:Script>
            <![CDATA[
                import Interfaces.IModuleInterface;
                import Interfaces.IObjectInterface;

                import mx.events.ModuleEvent;
                protected var module:IModuleInterface;
                protected var object:IObjectInterface;

                protected function ButtonLoadSwf_clickHandler(event:MouseEvent):void
                {
                    loader.unloadModule();
                    loader.url=moduleUrl.text;
                }

                protected function loader_readyHandler(event:ModuleEvent):void
                {
                    this.module = (loader.child) as IModuleInterface;
                }

                protected function ButtonCreateObject_clickHandler(event:MouseEvent):void
                {
                    this.object = this.module.giveMeObject(Number(TClassNumber.text));
                }

                protected function BCallMe_clickHandler(event:MouseEvent):void
                {
                    this.object.callMe();
                }

                protected function BCallMeToo_clickHandler(event:MouseEvent):void
                {
                    this.object.callMeToo();
                }
            ]]>
        </fx:Script>

        <fx:Declarations>
            <!-- Place non-visual elements (e.g., services, value objects) here -->
        </fx:Declarations>
        <s:Button id="ButtonLoadSwf" x="236" y="10" width="99" label="Load SWF"
                  click="ButtonLoadSwf_clickHandler(event)"/>
        <s:Button id="ButtonCreateObject" x="150" y="108" label="Create Object"
                  click="ButtonCreateObject_clickHandler(event)"/>
        <s:TextInput id="TClassNumber" x="96" y="107" width="46" text="1"/>
        <s:ModuleLoader x="10" y="39" width="325" height="60" id="loader" ready="loader_readyHandler(event)">
        </s:ModuleLoader>
        <s:TextInput id="moduleUrl" x="10" y="10" width="218" text="Modules/ModuleOne.swf"/>
        <s:Button id="BCallMe" x="96" y="137" width="150" label="callMe"
                  click="BCallMe_clickHandler(event)"/>
        <s:Button id="BCallMeToo" x="96" y="166" width="150" label="callMeToo"
                  click="BCallMeToo_clickHandler(event)"/>
    </s:WindowedApplication>

我建议你使用抽象工厂 这是一种非常灵活的方法,可以在不知道要实例化哪个类的情况下创建对象

在这个抽象工厂类中,您将需要导入所有可能创建对象的类别,这不需要您导入主类中的所有类别,但您仍然需要导入抽象工厂和接口以与新对象通信

下面是一个简单的例子:

/*
The interface you will use to communicate with your objects
*/
InterfaceForAllMyClasses.as
public interface InterfaceForAllMyClasses
{
    public function callMe();
    public function callMe2();
}

/*
Your Classes wich implement the interface
*/
Class1.as
import mypackage.InterfaceForAllMyClasses;
public class Class1 implements InterfaceForAllMyClasses
{
    public function callMe() { trace("called Class1"); }
    public function callMe2() { trace("called Class1 too"); }
}

Class2.as
import mypackage.InterfaceForAllMyClasses;
public class Class1 implements InterfaceForAllMyClasses
{
    public function callMe() { trace("called Class2"); }
    public function callMe2() { trace("called Class2 too"); }
}

/*
The Abstract Factory
*/
AbstractFactory.as
import mypackage.InterfaceForAllMyClasses;
public class AbstractFactory
{
    public function giveMeObject(classNumber:Number):InterfaceForAllMyClasses
    {
        switch(classNumber)
        {
            case 0: return(new Class1()); break;
            case 1: return(new Class2()); break;
            // for any new class that you add you must add a case entry here
        }
    }
}

/*
Your Program
*/
import mypackage.InterfaceForAllMyClasses;
import mypackage.AbstractFactory;
MyProgram.as
public class MyProgram
{
    var abstractFactory:AbstractFactory = new AbstractFactory();

    public function main()
    {
        var x:InterfaceForAllMyClasses=AbstractFactory.giveMeObject(0);
        var y:InterfaceForAllMyClasses=AbstractFactory.giveMeObject(1);

        x.callMe();
        x.callMe2();
        y.callMe();
        y.callMe2();        
    }
}
如果无法从主应用程序导入类,因为它们在外部模块SWF中声明,则可以将每个模块作为抽象工厂,例如:

Interfaces/IModuleInterface.as

package Interfaces
    {
        public interface IModuleInterface
        {
            function giveMeObject(classNumber:Number):IObjectInterface;
        }
    }

Interfaces/IObjectInterface.as

package Interfaces
    {
        public interface IObjectInterface
        {
            function callMe():void;
            function callMeToo():void;
        }
    }

Modules/ModuleOne.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"         implements="Interfaces.IModuleInterface">
        <fx:Script>
            <![CDATA[
                import Interfaces.IObjectInterface;
                public function giveMeObject(classNumber:Number):IObjectInterface
                {
                    switch(classNumber)
                    {
                        case 1:
                            trace("ModuleOne: Instantiating 1");
                            return(new ModuleOneClassOne()); 
                            break;
                        case 2:
                            trace("ModuleOne: Instantiating 2");
                            return(new ModuleOneClassTwo()); 
                            break;
                    }
                    return(null);
                }
            ]]>
        </fx:Script>
        <fx:Declarations>
            <!-- Place non-visual elements (e.g., services, value objects) here -->
        </fx:Declarations>
        <s:Label x="10" y="10" text="Module One Loaded"/>
    </s:Module>

Modules/ModuleOneClassOne.as

    package Modules
    {
        import Interfaces.IObjectInterface;

        public class ModuleOneClassOne implements IObjectInterface
        {
            public function ModuleOneClassOne()
            {
                trace("ModuleOneClassOne: Instantiated");
            }

            public function callMe():void
            {
                trace("ModuleOneClassOne: called callMe()");
            }

            public function callMeToo():void
            {
                trace("ModuleOneClassOne: called callMeToo()");
            }
        }
    }

Modules/ModuleOneClassTwo.as

    package Modules
    {
        import Interfaces.IObjectInterface;

        public class ModuleOneClassTwo implements IObjectInterface
        {
            public function ModuleOneClassTwo()
            {
                trace("ModuleOneClassTwo: Instantiated");
            }

            public function callMe():void
            {
                trace("ModuleOneClassTwo: called callMe()");
            }

            public function callMeToo():void
            {
                trace("ModuleOneClassTwo: called callMeToo()");
            }
        }
    }

AbstractFactoryInModules.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   width="345" height="200">

        <fx:Script>
            <![CDATA[
                import Interfaces.IModuleInterface;
                import Interfaces.IObjectInterface;

                import mx.events.ModuleEvent;
                protected var module:IModuleInterface;
                protected var object:IObjectInterface;

                protected function ButtonLoadSwf_clickHandler(event:MouseEvent):void
                {
                    loader.unloadModule();
                    loader.url=moduleUrl.text;
                }

                protected function loader_readyHandler(event:ModuleEvent):void
                {
                    this.module = (loader.child) as IModuleInterface;
                }

                protected function ButtonCreateObject_clickHandler(event:MouseEvent):void
                {
                    this.object = this.module.giveMeObject(Number(TClassNumber.text));
                }

                protected function BCallMe_clickHandler(event:MouseEvent):void
                {
                    this.object.callMe();
                }

                protected function BCallMeToo_clickHandler(event:MouseEvent):void
                {
                    this.object.callMeToo();
                }
            ]]>
        </fx:Script>

        <fx:Declarations>
            <!-- Place non-visual elements (e.g., services, value objects) here -->
        </fx:Declarations>
        <s:Button id="ButtonLoadSwf" x="236" y="10" width="99" label="Load SWF"
                  click="ButtonLoadSwf_clickHandler(event)"/>
        <s:Button id="ButtonCreateObject" x="150" y="108" label="Create Object"
                  click="ButtonCreateObject_clickHandler(event)"/>
        <s:TextInput id="TClassNumber" x="96" y="107" width="46" text="1"/>
        <s:ModuleLoader x="10" y="39" width="325" height="60" id="loader" ready="loader_readyHandler(event)">
        </s:ModuleLoader>
        <s:TextInput id="moduleUrl" x="10" y="10" width="218" text="Modules/ModuleOne.swf"/>
        <s:Button id="BCallMe" x="96" y="137" width="150" label="callMe"
                  click="BCallMe_clickHandler(event)"/>
        <s:Button id="BCallMeToo" x="96" y="166" width="150" label="callMeToo"
                  click="BCallMeToo_clickHandler(event)"/>
    </s:WindowedApplication>

考虑到赏金请求中的限制,答案是否定的,您需要在某个地方对该类进行硬引用,以便编译器将该类定义包含到您的项目中。但是,你只需要在任何地方引用一次。我使用了静态数组,比如staticconstdummy:array=[OneClass,TwoClass,ThreeClass];你制作了一个包含所有你想要的类的数组,并使用你想要的getDefinitionByName。我不需要声明,因为类名来自XML。将所有可能的条目添加到虚拟数组中,并使用通过XML传输的任何内容作为其参数。考虑到赏金请求中的限制,答案是否定的,您需要在某个地方对该类进行硬引用,以便编译器将该类定义包含到您的项目中。但是,你只需要在任何地方引用一次。我使用了静态数组,比如staticconstdummy:array=[OneClass,TwoClass,ThreeClass];你制作了一个包含所有你想要的类的数组,并使用你想要的getDefinitionByName。我不需要声明,因为类名来自XML。将所有可能的条目添加到您的虚拟数组中,并使用通过XML传输的任何内容作为其参数,我建议您仔细阅读这篇文章,因为仅导入类或包是不够的;我还建议创建一个包含
只有动态加载的类,所以您不会编译任何其他不必要的类。@Mircea,这似乎更接近我需要的。但不幸的是,它需要mxmlc。但是我使用的是flashide,我建议仔细阅读这篇文章,因为仅仅导入类或包是不够的;我还建议您创建一个只包含动态加载的类的包,这样您就不会编译任何其他不必要的类了。@Mircea,这似乎更接近我所需要的。但不幸的是,它需要mxmlc。但我使用的是Flash IDE,问题是,在编译之前,我仍然看到需要新的Class1和Class2。在我的例子中,swf已经编译,因此没有添加类声明的范围。类的名称直接来自XML,该类的主体出现在将被调用的swf中。好的,然后您可以将每个swf设置为抽象工厂,但确保它们都使用一个接口,下面是一个示例:请检查编辑,这是一个使用Flex的示例,您所需要做的就是通过所有对象使用相同的接口。请注意,使用接口并不是解决问题的唯一方法,但这将避免内存泄漏,而且对我来说,很多复杂的问题似乎是有希望的。Thnx!:问题是,我仍然认为在编译之前需要新的Class1和Class2。在我的例子中,swf已经编译,因此没有添加类声明的范围。类的名称直接来自XML,该类的主体出现在将被调用的swf中。好的,然后您可以将每个swf设置为抽象工厂,但确保它们都使用一个接口,下面是一个示例:请检查编辑,这是一个使用Flex的示例,您所需要做的就是通过所有对象使用相同的接口。请注意,使用接口并不是解决问题的唯一方法,但这将避免内存泄漏,而且对我来说,很多复杂的问题似乎是有希望的。Thnx!: