2009/08/22

ActionScript 3.0 root に関して

“未定義である可能性が高いプロパティ mc01 に静的型 flash.display:DisplayObject の参照を使用してアクセスしています。”

このエラーメッセージは、以下のように root からドットシンタックスでムービークリップのプロパティーとかにアクセスすると発生する。以下みたいな感じ。

root.mc01.x += 1;

結論から言うと、ActionScript 3.0 の root は、DisplayObject のプロパティーであり、DisplayObject は入れ子 (ネスト) に出来ないデータ型なので、子孫を持たない。つまり、root.mc01.x と書いた場合、root と mc01 は親子関係を表しているわけだから、root は子孫を持たないのでエラーになる、ということだと思う。
ActionScript 2.0 の頃は、_root は MovieClip だったので、入れ子に出来るデータ型だった。だから、_root.mc01._width というような書き方が出来たのである。

回避方法

root プロパティーは一番上の表示オブジェクトを返しているのは間違いないようなので、以下のようにネスト可能な型に変換 (キャスト) するとエラーが出ない。

MovieClip (root).mc01.width;

また、パブリッシュの設定で、エラーを出さないようにも出来る。

パブリッシュ設定 > Flash タブ > スクリプト:ActionScript 3.0 の「設定」ボタン

Strict モードのチェックを外す。

flash_strict

より細かい説明

ActionScript 3.0 では、画面に表示されるクラス (表示リスト) の中には、DisplayObject と DisplayObjectContainer というのがある。DisplayObject は、全ての画面に表示されるオブジェクトの元になるクラスで、ネスト不可なデータ型である。それに対して DisplayObjectContainer は、ネスト可能なデータ型の元になるクラスである。

以下は、画面に表示されるクラスのリスト (表示リスト) 。

こう思って ActionScript 3.0 コンポーネントリファレンスガイドを見ると良くわかる。

MovieClip のプロパティーを調べてみると、なんと root がある! root ってプロパティーなの? とか思いながらプロパティーの型を見ると DisplayObject となっており、定義元も DisplayObject となっている。今度は DisplayObject のプロパティーを調べてみると、やはり root があった。
root プロパティーの型は DisplayObject なので、つまり、入れ子にできない型なので、root の子供という指定ができないということである。

「DisplayObject」と「表示オブジェクト」は同じ

いろんなドキュメントを読んでみたが、これらがなかなか理解出来なかった。私が理解出来なかった理由として、英語と日本語が混在していたことが大きかったように思う。「DisplayObject」と「表示オブジェクト」は同じものを指しており、「DisplayObjectContainer」と「表示オブジェクトコンテナ」は同じものを指し示している。こう書くと当たり前なことのようで、こんな勘違いをしていたのは私だけかもしれないが、実際にドキュメントを読んでいる時には、漠然と違うものだと思って読んでいた。特に「DisplayObject」と「表示オブジェクト」は同じものを指し示しているとは思っていなかった。「DisplayObject」と書かれた場合は、クラスを指し示していると思っていたが、「表示オブジェクト」と書かれた場合は、表示する漠然とした概念かなにかのように感じていて、クラス定義を指し示しているとは思っていなかった。これに気付いた時に、初めて謎が解けたのである。

以下は、わかりやすいように一覧表にしてみた。

DisplayObject 表示オブジェクト ネスト不可
DisplayObjectContainer 表示オブジェクトコンテナ ネスト可能