Macromedia Flash非公式テクニカルノート 予め配置したMovieClipのリスナーがインスタンスのないフレームに移動してもイベントを受取る
問題 たとえば、メインタイムラインに2フレームをつくり、その第1フレームのみにMovieClipインスタンスを置きます(図001)。MovieClipインスタンスには、とくにビジュアルエレメントは要りません。 図001■全2フレームのメインタイムライン第1フレームにMovieClipインスタンスを置くMovieClipシンボルの第1フレームに、以下のスクリプト001を記述します(図002)。インスタンスには、DisplayObject.enterFrameイベント(定数Event.ENTER_FRAME)のリスナー関数(xTest())を登録します。 メインタイムラインの第2フレームにはMovieClipインスタンスがありませんので、第1フレームに戻るたびにインスタンスは新たに認識されます。そこで、インスタンスを識別するため、変数(id)にgetTimer()関数が返す整数を設定しています。そして、リスナー関数は、Event.typeプロパティのイベント名"enterFrame"と変数の整数値を[出力]します。 スクリプト001■MovieClipシンボルのフレームアクションでインスタンスにイベントリスナーを登録
図002■MovieClipシンボルに第1フレームアクションを記述 メインタイムラインの第1フレームには、以下のスクリプト002を書きます。DisplayObject.enterFrameイベントのリスナー関数(xFrame())から、ループ再生する再生ヘッドがどのフレームにあるのかを[出力]します。 スクリプト002■ループするメインタイムラインから再生ヘッドのあるフレームを[出力]
図003■メインタイムラインの第1フレームでDisplayObject.enterFrameイベントにリスナーを登録 [ムービープレビュー]を確かめると、メインタイムラインのフレームループを繰返すたびに、MovieClipインスタンスのリスナー関数が増えていくように見えます(図004)。 図004■フレームをループするたびにMovieClipインスタンスのリスナー関数が増えていく まずメインタイムラインの第1フレームで、MovieClipインスタンスのDisplayObject.enterFrameイベントにリスナー関数が登録されます。そして、つぎの第2フレームに進むと、MovieClipインスタンスはなくなっているのに、リスナー関数が呼出されています。 さらに、第1フレームにループで戻ると、改めてMovieClipインスタンスが認識されて、イベントリスナーが登録されます。しかし、前のループのリスナーは、まだイベントを受取っています。すると、つぎの第2フレームでは、MovieClipインスタンスはないにもかかわらず、ふたつのリスナー関数がイベントを受取ります。 こうして、メインタイムラインのフレームループを繰返すたびに、イベントリスナーが増えていくようです。 原因 実験としては、メモリを大きく費やすことで、ガベージコレクションを促すことはできます。たとえば、前掲スクリプト002につぎのステートメントを加えると、参照のないTextFieldインスタンスが大量につくられますので、ガベージコレクションは速やかに働きます(図005)。もちろん、メモリを浪費しているので実用には使えません。 図005■メモリを費やすとガベージコレクションが促される
対処法 たとえば、前掲スクリプト002であれば、つぎのようにDisplayObject.removedFromStageイベントでイベントリスナーを削除します(スクリプト003)。すると、インスタンスがなくなったフレームでは、イベントリスナーが呼ばれなくなります(図006)。 スクリプト003■MovieClipシンボルのフレームアクションにイベントリスナー削除の処理を加える
図006■インスタンスがステージから消えるときイベントリスナーを削除する 今回、MovieClipシンボルはテスト用に単純化して1フレームで済ませました。しかし、複数フレームをアニメーションしているときは、これもシステムのリソースを費やします[*3]。したがって、MovieClipインスタンスがタイムラインからなくなるときには、イベントリスナーの削除とともにフレーム移動を止めておくことも必要です。
作成者: 野中文雄 Copyright © 2001-2010 Fumio Nonaka. All rights reserved. |
|||||||||||||||