エラーにも“イベント”が
前回の「ActionScriptで頑張ればFlashゲームは無料で作れる 」でイベント の話を少ししたと思います。ある特定のタイミングを得たいときや、いつ得られるか分からない結果を取得するようなときはイベントを使うのですが、エラーにもイベントがあります。try-catch処理でキャッチできるエラーは「同期エラー 」といい、イベントリスナー でしかキャッチできないエラーを「非同期エラー 」といいます。
例えば、URLLoaderクラスなどを使用して通信処理を行う場合には、読み込みエラーや、セキュリティエラーなどの非同期エラーが発生する可能性が高いので、エラーイベントを扱うことになります。Flex で開発していると、非同期処理が多いため、実際はtry-catchよりもエラーイベントを扱うことが多いです。
ErrorEventクラス ネットワークおよび通信の操作に関係した、ランタイムエラーを管理するためのプロパティおよびメソッドが含まれるクラス。サブクラスはAsyncErrorEvent、IOErrorEvent、SecurityErrorEventなど
イベントリスナーの登録方法、イベントハンドラの記述方法は、前回説明した方法と同じです。復習もかねて以下のコードを入力してみましょう。
Lesson7_4.as
package {
//import文は省略
public class Lesson7_4 extends Sprite {
private var mySound:Sound;
public function Lesson7_4() {
mySound = new Sound()
stage.addEventListener(MouseEvent.CLICK, clickHandler); 【1】
}
private function clickHandler(event:MouseEvent):void { 【2】
test();
}
private function test():void {
try {
mySound.load(new URLRequest("sample.mp3"));
mySound.play();
} catch (err:Error) {
createTextField(err.message);
}
mySound.addEventListener(
IOErrorEvent.IO_ERROR, errorHandler); 【3】
}
private function errorHandler(errorEvent:IOErrorEvent):void { 【4】
createTextField(errorEvent.text);
}
private function createTextField(message:String):void {
var errorText:TextField = new TextField();
errorText.width = 600;
errorText.text = message;
addChild(errorText);
}
}
}
【1】clickHandlerメソッドを、ステージをクリックした際のイベントハンドラとしてイベントリスナーに登録
【2】ステージをクリックした際のイベントハンドラ
【3】errorHandlerメソッドを、IOErrorEvent.IO_ERRORが起きた際のイベントリスナーとして登録
【4】IOErrorEvent.IO_ERRORのイベントハンドラ
このコードでは同期エラーと非同期エラーの2つを確認できます。実行し、ステージをクリックしてみましょう。
図8 Lesson7_4.asの実行結果
まず、sample.mp3ファイルが存在しないため、入出力エラーが起きます。この入出力エラーは非同期エラーです。IOErrorEvent.IO_ERRORイベントが発行され、errorHandlerメソッドが実行されています。
では、皆さんのパソコン内にあるmp3ファイルを、Lesson7_4.asと同じフォルダにコピーし、sample.mp3という名前に変更して、再度実行してみましょう。音は鳴りましたか?
それでは、もう一度ステージをクリックしてみてください。今度は以下のようなエラーが表示されたと思います。
図9 エラーが発生
これはSoundクラスのloadメソッドはSoundオブジェクトに対し、1度しか実行できないために表示されているエラーです。2度目のloadメソッド実行時に、エラーがスローされ、catchステートメント内が実行されています。
では、このエラーが起きないように、finallyステートメントを追記し、その中でSoundオブジェクトを再生成しましょう。finallyステートメント内の処理は、エラーが起きても起きなくても最後に必ず実行される処理です。
} catch (err:Error) {
createTextField(err.message);
} finally {
mySound = new Sound();
}
いかがでしょうか。同期エラーのキャッチの方法、非同期エラーのキャッチの方法は理解できましたか? 参考までに、実際に開発する際にエラー処理をよく使う具体例を紹介します。
通信処理 入出力エラーやセキュリティエラー
ActionScript(やFlex)のライブラリを利用する際 ライブラリ内でエラーがスローされた場合のハンドリング
処理時間が非常に長い処理を行う場合 タイムアウトエラー
などなど……
カスタムエラークラスを作ってみよう
では、最後にErrorクラスを継承したカスタムエラークラスを作成してみましょう。カスタムエラークラスを作ることで、catchステートメントでの処理分けができたり、拡張することで、デバッグがしやすくなったりします。
以下のようなカスタムエラークラスを作ってみましょう。以下は、カスタムエラークラスの一例です。
MyCustomError.as
package {
public class MyCustomError extends Error {
public function MyCustomError(message:String="", id:int=0) {
super(message, id); 【1】
}
public function toString():String { 【2】
return "I am a MyCustomError";
}
}
}
【1】Errorクラスのコンストラクタが引数を取るため、MyCustomErrorのコンストラクタもそれに合わせている
【2】toStringメソッドのオーバーライド(※注意 :toStringメソッドはObjectクラスのprototypeなメソッドで、継承したすべてのクラスに自動的に割り当てられる。このメソッドはオーバーライドの際、override句は不要)
作成したカスタムエラーをスローしてみましょう。
Lesson7_5.as
package {
//import文は省略
public class Lesson7_5 extends Sprite {
public function Lesson7_5() {
test();
}
private function test():void {
throw new MyCustomError();
}
}
}
図10 Lesson7_5.asの実行結果
実行すると、図10 のようなダイアログが表示されます。MyCustomErrorクラスのtoStringの戻り値「I am a MyCustomError」が表示されています。try-catchの方法はいままでと同じです。
カスタムエラークラスを使うことで、アプリケーション固有のエラー処理ができ、デバッグもしやすくなりそうですね。
頭の中の「作りたいもの」を形にするきっかけに
今回はエラー処理について説明しました。エラー処理を上手に行うことで、きっとかゆいところまで手の届く良質なアプリケーションを作ることができると思います。
さて、ActionScript入門講座は今回で最終回となります。ここで説明したことが、皆さんの頭の中の「作りたいもの」を形にするきっかけになったら、とても幸せに思います。いままでお付き合いいただきありがとうございました。
プロフィール
吉村 美保(よしむら みほ)
クラスメソッド株式会社 情報システム部 プログラマー ゲーム開発、インストラクターなどの経験を経て、クラスメソッド株式会社に入社。入社後はFlexやAIRによるRIA開発を行っている。
Copyright © ITmedia, Inc. All Rights Reserved.