【问题标题】:AS3 class / static variable init timingAS3 类/静态变量初始化时序
【发布时间】:2017-07-22 09:57:30
【问题描述】:

我有一个纯 AS3 项目(没有 mxml)。

使用 flex SDK 4.6 编译时,类(及其静态变量)在被引用时(使用静态成员或创建类实例时)第一次被初始化。

使用 air SDK 24.0 编译时,许多类(及其静态变量)在应用程序启动时被初始化,而不是在它们被引用之前。为什么?是否有任何编译选项或 SWF 元标记来防止这种情况发生?

我的静态变量需要一些其他数据来初始化,这些数据是在运行时动态加载的,在应用程序启动时不会立即可用。所以,我不希望他们这么早被启动。

【问题讨论】:

  • 使用带有私有实例成员变量和公共静态getter/setter的单例blog.gskinner.com/archives/2006/07/as3_singletons.html
  • @autum Flex SDK 使用 ASC 1.0,而 AIR SDK 使用 ASC 2.0,这会导致不同的行为,例如您描述的行为。我同意使用上述方法。
  • 自我实现的“后期初始化”对于大单例来说是可以接受的,但当您在数百个类中有数百个运行时常量时,这不是一个好方法。它使代码冗长且无效。我坚持编译器应该做这项工作。而且这里没有提到:helpx.adobe.com/flash-builder/…

标签: actionscript-3 flash apache-flex


【解决方案1】:

我的静态变量需要一些其他数据来初始化,这些数据是 在运行时动态加载,在应用程序中不立即可用 开始。所以,我不希望他们这么早被启动。

开始这样做是危险的,即使它在 ASC 1.0 中有效。如果您需要在计算某些派生值之前加载数据,则不应依赖静态初始化。

您可以使用单例,或者只使用静态initialize() 方法,您可以在加载数据后显式调用该方法:

private function handleDataLoaded(e:DataEvent):void {
    MyStaticStuff.initialize(e.data);
}

或者,作为替代品,您可以将静态变量重构为内部调用 init 函数的 getter:

public class MyStaticStuff {
    // before
    public static const SOME_VALUE:Number = LoadedData.data.something;

    // after
    private var initialized:Boolean = false;

    private static _SOME_VALUE:Number;

    public static function get SOME_VALUE():Number {
        initialize();
        return _SOME_VALUE:Number;
    }

    private static function initialize():void {
        if (!initialized) {
            initialized = true;
            _SOME_VALUE = LoadedData.data.something;
        }
    }
}

在这种情况下,使用MyStaticStuff.SOME_VALUE 的地方不必更改,并且值将在第一次被引用时被初始化,就像以前一样。但重构代码以使用单例和/或显式初始化可能是一种更好的模式。

【讨论】:

  • “静态变量在其类被引用的第一时间被初始化”在许多编程语言中是必须的,例如 Java、C++。这样,代码就可以简单而有效:“public static var a:A = initA();”。只有一行。而且,对“a”的任何引用都只是一个变量引用。但是,当使用“late init”时,代码冗长、无效。所有对“a”的引用都成为方法调用,如果它只是一个大单例,那没关系,但对常量不利(我的意思是运行时间,而不是编译时间)。所以如果编译器中有一些选项会更好。
  • 是的,但是很难有效地推断何时一个类是“第一次引用”的。您正在编写脆弱的代码,即使它有效。当您知道要考虑依赖时间(在您的情况下异步加载数据)时,明确性总是更好。你破碎的项目就是一个很好的例子。您也许可以在 ASC 2 中对事物进行改组以使其表现不同,但我不能建议这是一个好主意。
  • 我知道依赖,我可以控制它,只需在应用程序启动时加载依赖的资源,加载完成后,初始化所有其他类。哦!我找到了一个解决方案:将所有其他类编译为一个模块,然后将模块 swf 嵌入到主 swf 中。在主 swf 中,首先加载资源,加载完成后,加载模块 swf,因此模块类在依赖资源之前永远没有机会被初始化。但也不是一个好的解决方案。
猜你喜欢
  • 2018-12-19
  • 2010-09-17
  • 1970-01-01
  • 2011-08-22
  • 2010-12-22
  • 2015-06-01
  • 2010-09-26
相关资源
最近更新 更多