Platform: All
Version: MX 2004
1. 現象
Flash MX 2004のMovieClipLoaderクラスを使用したとき、MovieClipLoader.onLoadInitメソッドを定義すると、コンパイルエラーを発生することがあります。スクリプトは、たとえばつぎのようなものです(スクリプト001)。
スクリプト001■MovieClipLoaderクラスを使ったサンプル
// フレームアクション
var my_mc:MovieClip;
var my_mcl:MovieClipLoader = new MovieClipLoader();
my_mcl.onLoadInit = function(target_mc:MovieClip) {
trace(target_mc);
};
my_mcl.loadClip("test.swf", my_mc);
|
エラーの内容(図001)は、onLoadInitというプロパティ(メソッド)が(MovieClipLoader)クラスに定義されていないというものです。
図001■[出力]されたActionScriptエラー
**エラー** シーン = シーン 1, レイヤー = Scripts, フレーム = 1 :行 4:onLoadInit' という名前のプロパティはありません。 my_mcl.onLoadInit = function(target_mc:MovieClip) {
|
2. 原因
MovieClipLoaderインスタンスに対して、ActionScript 2.0の「厳密な型指定」を行った場合に、この問題が発生します。スクリプト001は、第2ステートメント(4行目)で「var my_mcl:MovieClipLoader」と、インスタンスをMovieClipLoaderで型指定していました。このとき、MovieClipLoaderインスタンスにMovieClipLoader.onLoadInitメソッドを定義すると、コンパイルエラーになります。
型指定というのは、変数やプロパティに対して、そこに格納すべきインスタンスのクラスを宣言することです。すると、指定されたクラス以外のインスタンスを設定しようとしたり、そのインスタンスを参照してクラスに定義されていないプロパティやメソッドにアクセスしようとしたとき、コンパイルエラーを返します。
コンパイルエラーの原因は、後述します。結論としては、MovieClipLoaderインスタンスに直接イベントハンドラメソッドMovieClip.onLoadInitを定義するシンタックスは、サポートされません。Flash MX 2004 7.0.1のドキュメントからはこの点が明確でなく、MovieClipLoaderインスタンスに直接イベントハンドラメソッドを定義する解説も存在します(たとえばActionScript[org]「Using the MovieClipLoader」)。ファイルひとつをロードする単純なケースには、この簡潔な記述には魅力もあります。しかし、MovieClipLoaderクラスの仕様として意図されておらず、動作が保証されないようですので、このスタイルは差控えるべきでしょう。
コンパイルエラーを発生する理由は、MovieClipLoaderのクラス定義ファイルの内容にあります。Flash MX 2004のインストール時に作成されるユーザーのConfigurationフォルダにあるClassesフォルダ[*1]には、ActionScript定義済みクラスと同名のActionScriptファイルが格納されています。このフォルダの中に、MovieClipLoader.asも含まれています。
[*1]Classesフォルダ
オペレーティングシステムごとの具体的なフォルダのパスについては、Flash MX 2004オンラインヘルプの[ActionScriptリファレンスガイド] >[ActionScript 2.0によるクラスの作成] > [クラスパスについて] > [グローバルなクラスパスとドキュメントレベルのクラスパス]をご参照ください。 |
MovieClipLoader.asをActionScriptエディタ(Professional版に搭載。Standard版の場合はテキストエディタやコードエディタを使用)で開くと、つぎのような内容になっています(スクリプト002)。
スクリプト002■MovieClipLoader.as
//****************************************************************************
// ActionScript Standard Library
// MovieClipLoader object
//****************************************************************************
intrinsic class MovieClipLoader
{
function MovieClipLoader();
function addListener(listener:Object):Boolean;
function getProgress(target:Object):Object;
function loadClip(url:String, target:Object):Boolean;
function removeListener(listener:Object):Boolean;
function unloadClip(target:Object):Boolean;
function onLoadComplete(target:Object):Void;
function onLoadError(target:Object, errorCode:String):Void;
function onLoadProgress(target:Object, bytesLoaded:Number, bytesTotal:Number):Void;
function onLoadStart(target:Object):Void;
}
|
classステートメントの先頭に、intrinsicという「ActionScript辞書」に記載のないキーワードが指定されています。そして、クラス本体のプロパティやメソッドについては、型指定がされているのみです。とくにメソッドについては、実際の処理内容(実装)が記述されていません。
intrinsicクラスでは、型指定のみが定義されます。これは、コンパイラが型チェックを行うために用意されたものです。そこで注目されるのは、MovieClipLoaderクラスにonLoadInitのfunction定義だけが存在しないことです[*2]。これが、コンパイルエラーの原因です。intrinsicクラスMovieClipLoaderの定義に、onLoadInitメソッドの宣言と型指定がないため、コンパイル時に未定義メソッドへのアクセスが行われているものと解釈されてしまうのです。
[*2]intrinsicクラス内のメソッド定義
MovieClipLoaderのintrinsicクラス定義ファイルには、他のイベントハンドラメソッド(たとえば、MovieClipLoader.onLoadCompleteやMovieClipLoader.onLoadError)は定義されています。これらのイベントハンドラメソッドについても、MovieClipLoaderインスタンスに直接定義することは問題です。
したがって、MovieClipLoader.onLoadInitメソッドだけがintrinsicクラス定義から漏れているのは、一種のバグというべきです。インスタンスへの直接定義を警告するためにMovieClipLoaderクラス定義から外すのであれば、他のイベントハンドラメソッドも同様に削除すべきでしょう。
|
3. 対処法
MovieClipLoaderクラスを使うには、まずリスナーオブジェクトを作成し、MovieClipLoaderインスタンスにリスナーとして登録する必要があります。イベントの発生に対するコールバック関数は、MovieClipLoaderインスタンスでなく、リスナーオブジェクトに対して定義します。
スクリプト003■リスナーオブジェクトを作成してMovieClipLoaderインスタンスに登録
// フレームアクション
var my_mc:MovieClip;
var my_mcl:MovieClipLoader = new MovieClipLoader();
var oListener:Object = new Object();
oListener.onLoadInit = function(target_mc:MovieClip) {
trace(target_mc);
};
my_mcl.addListener(oListener);
my_mcl.loadClip("test.swf", my_mc);
|
_____
作成者: 野中文雄
更新日: 2004年6月22日 対処法をリスナーオブジェクトを作成する方法に修正
作成日: 2004年5月31日