« Windowsで保存の際のショートカットリスト?に任意のドライブ、フォルダを追加できないのか? | Home | catch、catchって »

Mar 242008

getDefinitionByNameの罠

ちとプレビュー前でばたばたしているので走り書きだけど、たとえばプリロードみたいなやり方で、メインコンテンツを先に展開しつつ、後追いで優先度の低い埋め込みリンケージサウンドなんかを実体化させる場合、スクリプト内で"getDefinitionByName"を使って定義しちゃうと、実体化の前に定義できてしまう。(try,catchでも一応定義はされているということでスルーされてしまうっぽい、そもそも定義自体がされていない場合はReferenceErrorをcatchできます。)

生成されたサウンドクラスは値はnullにもならず、よく分からない空の状態で定義されてしまって、soundChannelとかsoundEventでエラーが連発して悲惨な状況になる。

なので実体化されているかどうか?の確認は

try{
	var className:Class = getDefinitionByName(sndID) as Class;
	var snd:Sound = new className() as Sound;
	if (snd.length > 0) return snd;
}catch (e:ReferenceError) {
	return null;
}
みたいな感じになるかと・・。 非常に厳密にエラー定義がされている割には、この手の抜けっぷりが非常にうっとおしいですな。実体化されているかどうか?もcatch出来るようにしてくれれば良いのに・・・。

もちっとローディングの分散の手法はAS3で的確な方法があるのかもしれないが、まだAS2との折衷みたいな段階で煮詰め切れていない。

今一つ使っている手法としては、でかいサウンド系は外部SWFファイル埋め込んでおいて、

var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
の定義をしておいて、Event.COMPLETEの発動=実体化として認識してしまう形にすれば、getDefinitionByNameでReferenceErrorを取得することは可能(なはず)。

取り急ぎメモ。
間違っていたらゴメン。

3 Comments

こんにちわ。

hasDefinition(sndID)
を調べたらどうなるんでしょう?

ちょっと試す余裕がないのですが、
var className:Class = getDefinitionByName(sndID) as Class;
でエラーがcatchされないということは
hasDefinition(sndID) = true
な状況ではないかと思います。

つまり実体化される前にライブラリ内で名前だけは定義されていて、その有無だけを見ているような気がします。

ちと時間できたら確認しますです。

検証してみました。
リンケージサウンドを実体化する前にタイムラインMCで以下を実行。
trace(this.loaderInfo.applicationDomain.hasDefinition("snd_click"));
//>true
ということで推測していたとおり、trueが戻ってきました。(つまり定義はされている)

恐らくクラスIDを保持しているテーブルは、そのクラスの実体とは関係なく管理されておりReferenceErrorはそのテーブルのみを参照しているのではないでしょうか・・。

で、この定義管理テーブルがどのタイミングで読み込まれるか?を調べる必要がありますが、これが1フレーム目固定であったとするならば、クラス書き出しフレームを10フレーム目等に変更した場合、1フレーム目でnew hogehoge();してもエラーも起きず、中身の存在しないオブジェクトが生成されるんじゃないかな・・と思います。(これも時間できたら確認しますけど、3月中はとりあえず無理)

しかしAS3ってこういうちょっとした検証するの面倒ですね・・。

Leave a comment

Search and Archives