【问题标题】:Objects on stage are not initialized outside constructor舞台上的对象未在构造函数之外初始化
【发布时间】:2012-11-25 13:54:18
【问题描述】:

在我的文档类中,我已将一些放置在舞台上的对象分配给一个数组,以便稍后调用它们。

当我在构造函数之外声明数组时,对象尚未创建并且赋值为空,这与我在构造函数中声明它们时不同。 为什么会发生这种情况?

如何我可以避免这种情况?可以使用监听器来跟踪对象的加载时间吗?

第一个案例

package { 
   public class Document extends MovieClip {
       var obj:Array = [object1,object2];
       public function Document() {
          trace(obj[0]); // <-- null
       }
   }
}

第二种情况

package { 
   public class Document extends MovieClip {
       public function Document() {
          var obj:Array = [object1,object2];
          trace(obj[0]); // <-- reference value
       }
   }
}

【问题讨论】:

    标签: actionscript-3 constructor flash-cs6


    【解决方案1】:

    在外面声明数组,在构造函数里面填充值。

    public class Document extends MovieClip {
       var obj:Array;
        public function Document() {
          obj = [object1,object2];
          trace(obj[0]); // <-- reference value
       }
    }
    

    无论你写什么作为初始化值都会被首先处理,任何嵌入在编辑器中的东西都是第二个,构造函数代码是第三个。因此,当您在初始化代码中按名称引用资产时,它们尚未初始化,因此您会收到空值。

    您使用的任何侦听器都只会在对象可用后应用。 init()ADDED_TO_STAGE 侦听器非常有用,如果您需要舞台参考以将您的代码控制资产与给定的舞台尺寸对齐。在此之前,阶段引用为空。

    【讨论】:

    • 我知道我的问题是为什么会这样?
    • 因为您在声明中使用代码初始化的所有内容都会先处理,阶段元素会先处理,构造函数代码会先处理。因此,当处理构造函数外初始化代码时,object1object2 尚未初始化,因此您会得到空值。
    • @Vesper 如果需要,您可以使用评论更改当前答案,正确答案是您的。另一件事,我可以使用Event Listener onLoad,一些init()函数,ADDED_ON_STAGE还是没有必要?
    • 在这种情况下不需要使用那些监听器
    【解决方案2】:

    全局变量(即任何方法之外的变量)在任何事情之前加载之后构造函数被调用,之前它被执行.

    改用此代码:

    package { 
       public class Document extends MovieClip {
           var obj:Array;
           public function Document() {
              obj = [object1,object2];
              trace(obj[0]);
           }
       }
    }
    

    附录:

    Stage 对象在构造函数代码的顶部被初始化,例如 .net 中的设计器对象。

    因此,由于全局变量在构造函数代码执行之前被初始化,object1object2 仍然是null

    附录 2:

    你有以下序列:

    1. 类的构造函数被调用
    2. 全局变量已初始化(您的 obj 数组,还有 object1/object2 变量,但不是它们的值)
    3. Designer(你在舞台上的图形)对象被初始化(即object1 = new Object1()被调用)
    4. 构造器代码被执行

    舞台对象总是自动声明和初始化,除非您在高级 AS 设置中取消选中自动声明舞台实例

    【讨论】:

    • 你能解释一下为什么在放置舞台对象之前调用 Document 构造函数吗?
    • 对象是 Document 的子对象,因此 Document 必须在它们之前创建。
    • 我发现最容易把它想象成舞台(就像在 IDE 文档中放置对象的地方)是从文档类继承。这意味着在子类(IDE 阶段)被实例化之前,文档类对舞台上声明的对象没有任何概念。
    • @DaveHart 很好的解释,有没有办法证明对象是在舞台上创建的,或者在我们调用构造函数时是隐含的?
    【解决方案3】:

    嗯,这有点模糊。这些对象在哪里实例化? 我建议确保它们在您的课程中被实例化:

    package
    {
        public class Document extends Sprite //I don't think you really need MovieClip
        {
            //alternatively to the method bellow you could use something like:
            //
            // private var object1 : Object = new Object();
            // private var object2 : Object = new Object();
            // public var obj : Array = [object1, object2];
            //
            // just make sure they are instantiated before they are used in the obj contructor
    
            public var obj : Array = [new Object(),new Object()]; //again here I would suggest using a vector if they are the same type
    
            public function Document()
            {
                trace(obj[0]);
            }
        }
    }
    

    如果这些对象在类外部,我建议将它们传递给构造函数,如下所示:

    package
    {
        public class Document extends Sprite //I don't think you really need MovieClip
        {
            public var obj : Array = [null,null]; //again here I would suggest using a vector if they are the same type
    
            public function Document(o1:Object=null,o2:Object=null)
            {
                if (o1 != null)
                    obj[0] = o1;
                if (o2 != null)
                    obj[1] = o2;
                // 
                if (obj[0] != null)
                    trace(obj[0]);
                else
                    trace("Obj[0] is null");
            }
        }
    }
    

    [稍后编辑] 至于发生这种情况的原因是因为在数组初始化时这两个是空的(它们还没有被初始化)

    [稍后编辑2] OK - Document 是 flash 的根类 - 很高兴知道 就像我在我的 cmets 中所说的那样,即使在舞台上这两个对象在添加到舞台之前不会被实例化。为此,我建议收听 ADDED_TO_STAGE 事件。 如果您将它们传递到构造函数之外,则在创建数组时它们将为空,因为它们尚未添加到阶段/创建(与流行的看法相反,即使在 Flash 中,对象也不会简单地存在)

    【讨论】:

    • 不,他们在舞台上。请阅读问题!
    • 在投 -1 票之前,请务必阅读答案。话虽如此,请解释一下您希望您的班级如何真正知道这些对象是谁?你在哪里传递对这些对象的引用?就像我之前在你的问题中说的更具体,你会得到更准确的答案。只要你没有正当理由,投-1票来诋毁别人只会让你被禁止。
    • 不想诋毁你,但你的回答并没有为帖子添加有用的东西。你写了“嗯,这有点模糊。那些对象在哪里实例化?”,所以这意味着你实际上没有读过这个问题,因为@yannis hristofakis 指定对象在舞台上。在 Flash 中,舞台上的对象会自动声明和初始化(除非您标记了特定选项)。
    • 我不知道你从哪里学过 Flash 但显然你的老师很差。在舞台上声明的 Flash 对象并非在该 swf 中的所有类中都可用。为了使对象在类中可用,它们必须被具体实例化// 传递给类。即使在舞台上,它们也不会在舞台实际显示之前被实例化 - 因为有 Event.INITIALIZE 和 Event.ADDED_TO_STAGE - 我知道你认为这些是无用的事件,但它们确实不是。哦,@teejay 请不要炫耀你的 Flash 知识有多低。
    • Document类是主舞台类的总称,自Flash CS3起,无需假设。 active.tutsplus.com/tutorials/actionscript/…
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2012-06-30
    • 2012-03-05
    • 2021-11-06
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    相关资源
    最近更新 更多