【问题标题】:Import Class Globally in AS3/Flash CS5在 AS3/Flash CS5 中全局导入类
【发布时间】:2011-12-11 05:40:42
【问题描述】:

我有一个使用 ActionScript 3、Flash Professional CS5.5 和 AIR 3 的项目。

我有几个需要访问的自定义类。目前,我通过传统方式成功访问:

import trailcrest.core.core;
var Core:core = new core();

但是,我在我的代码中实现了...这会创建类的副本,并且不提供对原始文件的访问权限。这当然是一个问题——我需要一个符号的脚本来修改类中的一个变量,而另一个符号的脚本访问该更改的变量。显然,现在还没有发生。

我该如何做我所描述的?我是否应该以某种方式为班级创建一个“公共变量”(尽管我需要有关如何做到这一点的说明......我不能在阶段或符号中使用“公共变量”)?有什么方法可以直接访问类吗?

帮助!并提前致谢。

【问题讨论】:

    标签: flash actionscript-3 class static flash-cs5


    【解决方案1】:

    这可以通过使用Singleton design pattern 很好地完成。 这是示例 AS3 实现:

    package   {
    
    public class SomeClass {
    
        /** Singleton instance */
        private static var instance : SomeClass;
    
        /** This instance variable will be accesible globaly by calling it SomeClass.getInstance().somePublicVar */
        public var somePublicVar    : * ;
    
        /**
         * Get singleton instance of class
         * @return  singleton instance  SomeClass
         */
        public static function getInstance () : SomeClass {
            return SomeClass.instance ? SomeClass.instance : ( SomeClass.instance = new SomeClass() );
        }
    
    }
    

    }

    【讨论】:

      【解决方案2】:

      通常认为使用全局变量是不好的做法。它通常会导致代码缺乏灵活性并且在您引入一些更改或进行修改时很容易中断。

      import trailcrest.core.core;
      var Core:core = new core();
      

      这很好!

      如果一个 Object 需要改变 Core 中某个属性的值,你只需要通过 dispatch 一个 Event 来通知 Core 值的改变。

       var object:MovieClip = new MovieClip();
       object.dispatchEvent ( property );
      

      在这种情况下,Core 作为您的文档类似乎是有意义的,在这种情况下,它会知道您的应用程序中的所有对象,无论是孩子、孙子等等...

      如果它不是您的文档类,那么您可以这样做...

       //In the Document Class
       var Core:core = new Core();
       var object:MovieClip = new MovieClip();
      
       // CoreEvent being a Custom Event
       object.addEventListener( CoreEvent.CHANGE , changeListener );
       addChild( object );
      
       //in another part of the Document Class
       //after a value has changed
       object.dispatchEvent ( property );
      
       //a method of the Document Class
       private function changeListener( event:CoreEvent ):void
       {
            var propNewValue:Object = event.property;
            //If you're using a singe instane of Core in the Document
            //Class, any other symbol can now access the new value.
            core.property = propNewValue;
       }
      

      如果在应用程序的其他部分创建对象,则始终可以将 Core 的实例作为参数传递。

        //In the Document Class
        var newobject:MovieClip = new CustomClass( core );
      

      编辑

      如果您觉得这个答案令人困惑,您可能应该阅读 OOP 的基本原则以及 AS3 中的事件调度。 Signals library 可能是有趣的东西,它是事件调度的一个不错的替代品。

      一般的想法是避免将您的对象绑定到单例或任何类型的全局变量。理论上,一个 Object 应该只知道它自己,您可以使用 Events for Objects 在它们之间进行通信。

      【讨论】:

      • 坦率地说,这个答案相当令人困惑......你能澄清一下吗?这如何解决我的问题?
      【解决方案3】:

      最好的方法是创建一个叫做“singleton”的东西。很简单,单例是一个静态类,没有静态类的所有讨厌的缺点。它使单个实例(或单个副本)在全局范围内可用,然后其行为与常规实例完全相同(因为它是)。

      通过使用静态变量和函数可以实现单例。静态变量/函数是 的一部分,而不是实例。因此,每个变量只能有一个(只有一个类)并且它们都是全局可访问的。静态函数和属性的一个很好的例子是内置的Math 类。你得到 Pi 的值是这样的:

      Math.PI
      

      不是这样的:

      var math:Math = new Math();
      math.PI
      

      如您所见,它是具有方法的类。我们可以通过提供一个静态的getInstance() 函数来使用它来创建一个单例,该函数将是全局可访问的,并且总是返回相同的对象。这是单例的示例实现:

      package {
      
          public class SingletonSample {
      
              // The singleton instance
              private static sharedSingleton:SingletonSample = null;
      
              // The constructor. AS3 doesn't allow for private constructors
              // so we have to protect it manually
              public function SingletonSample() {
                  if (sharedSingleton != null)
                      throw new Error ("SingletonSample cannot be created with the new keyword. Use getInstance() instead.");
              }
      
              // The method that will get the actual instance
              public function getInstance():SingletonSample {
                  if (sharedSingleton == null)
                      sharedSingleton = new SharedSingleton();
                  return sharedSingleton;
              }
      
          }
      
      }
      

      除了示例中定义的那些方法和变量之外,该类的其余部分都可以正常编程。然后,当您想在代码中使用该类时,不要这样做:

      var instance:SingletonSample = new SingletonSample();
      instance.doAThing(instance.aProperty);
      

      这样做:

      var instance:SingletonSample = SingletonSample.getInstance();
      instance.doAThing(instance.aProperty);
      

      实际上,当您只是快速调用方法时,根本不需要创建局部变量。只需执行以下操作:

      SingletonSample.getInstance.aQuickFunction();
      

      只要 SingletonSample 类已经被导入,这一切都是全局可用的。这种设计模式是一个很棒的“管理器”类,因此它可能会满足您的需求。但请记住,单例通常不适合作为可操作对象。如果您愿意,可以将它们用作提供对其他事物的引用的经理,一种“中间人”类。但是,如果使用得当,它们可以成为程序员武器库中强大而方便的工具。

      【讨论】:

      • 你应该避免用异常阻塞 Class 构造函数。与单元测试的兼容性很重要,因为很难正确测试 Singleton。我通常只是使用 ASDoc 来在单例中记录该类。
      【解决方案4】:

      您可以考虑使用静态类变量,例如:

      package trailcrest.core {
          import trailcrest.core.core;
          public class YourCustomClass {
              public static var coreReachableFromAnywhere:Core //THE STATIC VARIABLE FOR CORE
          }
      }
      

      然后在您的孙代码中:

      import trailcrest.core.YourCustomClass;
      yourCustomClass.coreReachableFromAnywhere = new Core();
      yourCustomClass.coreReachableFromAnywhere.someMethod() ...
      

      编辑

      当然,按照其他人的建议添加单例类型的方法会使其更加简洁,我也会对他们的答案进行投票。

      【讨论】:

      • 现在,这会进入文档类吗?另外,这是否允许我修改核心中的变量?
      • 假设我没看错,如果您只是将变量更改为“public static varbialbeName”,您应该可以通过 Core.varbialbeName 从任何地方静态访问它
      • 好的,这在大多数情况下都很好用。但是,我有一个 MovieClip 符号(它是一个曾曾孙,这是不可避免的),它不能通过“Core.testvar”访问变量“testvar”,这与舞台不同。那里发生了什么? (顺便说一句,它是“public static var”,而不仅仅是“public static”......希望你不介意这个小编辑。)
      • 如果你想静态访问它,你可以设置一个等于那个曾孙的静态变量。在你的类代码中有一个public static var someMC:MovieClip 然后在可以访问曾孙的代码中:Core.someMC = grandchildMC; 然后从那时起你可以静态访问grandchildMC。请记住,这算作垃圾收集的“参考”,如果您需要销毁对象,请设置静态变量 someMC = null
      • 嗯,不,我不想访问孙子。我想让孙子访问 Core。
      猜你喜欢
      • 1970-01-01
      • 2011-09-25
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多