如果使用 Flash Builder 4.7 而不是 4.6,基 class 中的静态函数不想调用子 class 上的成员函数

Static function in base class not wanting to call member functions on subclasses if using Flash Builder 4.7, instead of 4.6

从昨天开始,我一直在尝试将一个 ActionScript Mobile 项目从 Flash Builder 4.6 移植到 Flash Builder 4.7,但我 运行 遇到了一个可能是编译器错误的小问题。在 FB 4.6 中,这有效:

Temp.as:

package
{
    import flash.display.Sprite;

    public class Temp extends Sprite
    {
        public function Temp()
        {
            new StartMenu();
        }
    }
}

Screen1.as:

package
{
    import flash.display.*;

    internal class Screen1 extends Sprite
    {
        private static var m_vScreens:Vector.<Screen1> = new Vector.<Screen1>();

        public function Screen1()
        {
            m_vScreens.push(this);

            onScreenSizeDetermined();return;
            var strFunction:String = "useSmallPortraitLayout";
            for each (var screen:Screen1 in m_vScreens)
            {
                trace(1)
                screen[strFunction]();
            }
        }

        protected function useSmallPortraitLayout():void
        {
        }

        private static function onScreenSizeDetermined():void
        {
            var strFunction:String = "useSmallPortraitLayout";
            for each (var screen:Screen1 in m_vScreens)
            {
                trace(2)
                screen[strFunction](); // Error thrown here in 4.7.
            }
        }
    }
}

StartMenu.as:

package
{
    public final class StartMenu extends Screen1
    {
        override protected function useSmallPortraitLayout():void
        {
        }
    }
}

但在 4.7 中,它不起作用。我得到的错误是这样的:

ReferenceError: Error #1069: Property useSmallPortraitLayout not found on StartMenu and
there is no default value.

话虽这么说,但至少可以通过以下两种方式之一解决此问题:

  1. 使用 Flash Builder 4.6
  2. 注释掉onScreenSizeDetermined();return;,从而使用成员函数调用useSmallPortraitLayout(),而不是静态函数。这不需要使用构造函数;它工作得很好,只要 Screen1 从几乎任何非静态方法调用 useSmallPortraitLayout()

不幸的是,静态方法会失败,即使它是从构造函数外部 and/or 定时延迟调用的。有一件事我没有特别记得 在 4.6 中,但我至少在 4.7 中看到它,是使用不相关的 class 直接通过实例调用静态方法不会编译 - 它必须在不相关的 classes 中以静态方式完成。并不是说我在实际代码中做那样的事情,但它确实让我怀疑静态和非静态之间的关系是否有意改变。

这可能只是 FB 4.7 特有的一些微不足道的编译器错误,我会直接回到 4.6,但纯 ActionScript 库项目仅在 4.7 中直接受支持。 (这是一个移动项目,但我打算将一个库项目添加到解决方案中。)

需要注意的一点是,如果静态函数以这种方式调用 useSmallPortraitLayout,代码将无法在 FB 4.7 中编译:

screen.useSmallPortraitLayout();

它必须动态调用它才能编译。

是否有足够简单的修复方法? 4.6 一直忽略了一些句法上的奇怪之处吗?有什么不对,有什么好处solution/work-around?

更新

如果最坏的情况发生,用 Vector.<Function> 部分替换 Vector.<Screen1> 似乎确实有效,然后只调用函数向量的成员,而不是调用函数Screen1 向量的成员。 (这是从生产代码中简化而来的。)但这只是后备。

此外,我以前没有太注意的事情(特别是就这个问题而言),但 BotMaster 引起了我的注意,是在从 FB 4.6 开始的过程中到 FB 4.7,我也从 AIR 3.1 到 AIR 3.4。

我认为这更像是一个范围问题。受保护的方法只能在实例范围内调用,不能在静态范围内调用。当然,将修饰符更改为 public 可以解决这里的问题。 PO 可能会争辩说这里需要 protected 但实际上如果有意在该实例范围之外的实例上直接调用方法那么逻辑上该方法需要是 public.

顺便说一句,FB 4.6 编译器由使用的 AIR/FLEX SDK 提供,因此与使用相同 SDK 的 FB 4.7 的行为不会有区别。

Flash Builder 4.7 使用 ASC 2.0 编译 ActionScript 项目。从发行说明中,强调添加:

ASC 2.0 is a new compiler for ActionScript® 3.0 (AS3). It has stricter adherence to the AS3 language specification, includes compilation performance improvements, is more stable under memory pressure, and contains some demonstration optimizations that can be optionally enabled (in-lining, dead code elimination).

我怀疑编译器发现 useSmallPortraitLayout() 未在您的原始代码中引用,并且已从 ABC 输出中删除。