1

我有一个程序,我在其中为舞台创建了一个单例类,这样我就可以在我的其他类中访问它。

我还有一些其他符号,其中包含文本,因此需要在代码中修改文本。

我的问题是,每当我使用 TLF 文本而不是经典文本时,我的任何引用单例阶段类的类都会得到一个“TypeError: Error #1009: Cannot access a property or method of a null object reference."

我以前的程序可以很好地处理 TLF 文本,但这是我第一次在舞台上使用单例类,所以我猜它以某种方式涉及到这一点。

我在其他帖子中尝试了一些解决相关问题(例如发布设置)的解决方案,但到目前为止没有任何效果。

下面是第一个错误发生的地方:

// Constructor
    public function Zoom(object:MovieClip) {
        // Set the stage
        stage = StageManager.instance.stage;

        // Set the zoom object
        zoomObject = object;            

        // Add event listener for the mouse wheel
        stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseZoom); // ERROR OCCURS HERE

        if (Controls.instance.controls.zoomInBtn && Controls.instance.controls.zoomOutBtn) {
            Controls.instance.controls.zoomInBtn.addEventListener(MouseEvent.CLICK, zoomIn);
            Controls.instance.controls.zoomOutBtn.addEventListener(MouseEvent.CLICK, zoomOut);
        }
    }

这是单例类:

package {
import flash.display.Stage;

// Singleton class so any other classes can access the stage.
public class StageManager {

    // Publicly accessible singleton instance
    public static var instance:StageManager = new StageManager();

    private var m_stage:Stage;

    // Getters and Setters
    public function set stage(stg:Stage):void {
        m_stage = stg;
    }

    public function get stage():Stage {
        return m_stage;
    }
}
}
4

2 回答 2

0

首先,将 API 方法/属性名称用于您自己的类的属性/方法名称确实是不正确的。这让人很困惑。

其次,如果它抛出空错误,那么您尝试访问的属性的对象(阶段)为空,现在可能有很多原因,例如在设置阶段属性之前调用这行代码或更简单的阶段不可用被分配到舞台(现在你明白我为什么要为自己的类道具使用相同的名称了吗?)同样,可能是你的代码在 DisplayObject 的舞台属性可用之前执行(内容未添加到舞台)并且你的类不检查它是否不为空。

您显示的代码示例写得不好,即使是“单例”类也不是正确的单例类。

现在解决方案:

  • 查看您的代码设计并更改它阅读有关设计模式的信息(至少对于单例)
  • 跟踪 StyleManager 中的阶段值,以便查看是否以及何时设置了属性,还可以在 Zoom 构造函数中跟踪
  • 始终使用 try catch 块或至少测试您的代码所依赖的对象是否存在

如下:

if(stage) 
{
    stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseZoom);
}
else
{
    trace("[!] Expected stage but got null");
}

或者

try
{
    stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseZoom);
}
catch(err:*)
{
    trace("[!] Expected stage but got null\n"+err);
}
  • 切勿在您自己的类中使用 ActionScript API 使用的相同名称,以避免混淆并使调试更容易:)
  • 如果您依赖舞台属性不为空,请使用以下代码段:

这与 FlashDevelop 生成新的 Main 类完全相同,并且效果很好:

if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init, false, int.MAX_VALUE, true);

和初始化处理程序

protected function init(e:Event = null):void
{
    removeEventListener(Event.ADDED_TO_STAGE, init);
    //do here whatever is needed when stage proeprty is NOT null
}

此致

于 2012-06-28T08:54:04.317 回答
0

这个问题可能很古老,但我最近遇到了类似的问题,由于我对 TLF 缺乏经验,这非常令人困惑,无论如何它已被弃用,但我仍然需要使用可以相互流入的文本字段 - 足够简单,除非您正在使用 Flash。所以我很高兴为此使用 CS6。

无论如何,我的解决方案只是从我的构造函数中删除事件侦听器并将其放置在第一帧的时间线中;舞台加载,一切正常——只有我的自尊因为没有深入了解以使其正常工作而受到伤害。

我一直认为构造函数首先运行 - 并且以前从未遇到过将事件分配到那里的问题,也许现在我知道得更好,但不是很多。

这可能是因为加载 TLF 组件会在加载阶段时产生延迟?当然,舞台是先来的,一切都是它的孩子吗?疯狂!

于 2015-05-10T20:34:54.073 回答