我有一个程序,我为舞台创建了一个单例类,以便我可以在其他类中访问它。
我还有一些其他符号中包含文本,因此需要在代码中修改文本。
我的问题是,每当我使用 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;
}
}
}
首先,将 API 方法/属性名称用于您自己的类的属性/方法名称实际上是不正确的。这让人感到困惑。
其次,如果它抛出 null 错误,那么您尝试访问的属性的对象(阶段)是 null,现在可能有很多原因,例如,在设置阶段属性之前调用这行代码,或者更简单的阶段不可用于分配给阶段(现在你明白为什么我说对自己的类 props 使用相同的名称了?同样,可能是您的代码在 DisplayObject 的舞台属性可用之前执行(内容未添加到舞台),并且您的类不检查它是否不为 null。
您显示的代码示例编写得很差,即使是类似"单例"的类也不是正确的单例类。
现在的解决方案:
- 查看代码设计并对其进行更改 阅读有关设计模式的信息(至少对于单例)
- 在 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 nulln"+err);
}
- 切勿在您自己的类中使用 ActionScript API 使用的相同名称,以避免混淆并使调试更容易:)
- 如果依赖于阶段属性不为 null,请使用以下代码片段:
这与FlashDevelopment产生新的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
}
此致敬意
这个问题可能很古老,但我最近遇到了类似的问题,由于我对 TLF 缺乏经验,这非常令人困惑,无论如何它已被弃用,但我仍然需要使用可以相互流入的文本字段 - 除非您使用 Flash,否则非常简单。因此,我很高兴为此与CS6一起运行。
无论如何,我的解决方案只是从构造函数中删除事件侦听器并将其放置在第一帧的时间轴中; 阶段加载并且一切正常 - 只有我的骄傲因为理解不够深入而受到伤害,无法使其正常工作。
我一直认为构造函数首先运行 - 并且以前从未遇到过将事件分配给那里的阶段的问题,也许现在我知道得更多,但不是很多。
这可能是因为加载 TLF 组件会在加载舞台时产生延迟吗?当然,舞台是第一位的,之后的一切都是它的孩子?疯狂!