ActionScript 3
「エラー1009:nullオブジェクト参照のプロパティまたはメソッドにアクセスできません」について
サーチ…
前書き
null
変数またはプロパティから値を受け取ろうとするときに発生する一般的なエラーです。提供された例では、このエラーが発生するさまざまなケースと、エラーを緩和する方法に関するいくつかの推奨事項が公開されています。
備考
おそらく "エラー1009:nullオブジェクト参照のプロパティまたはメソッドにアクセスできない"という恐ろしい言葉は、データの一部がnullと表示されているが、入力されたオブジェクトとして使用しようとしているという信号です。この動作を引き起こす可能性のある問題のタイプはかなり多くあり、それぞれがエラーが発生したコードに対してテストする必要があります。
ステージが利用できません
開発者は、 stage
へのアクセスを望むコードやFlashステージを作成してリスナーを追加することがあります。それは初めて働くことができますし、突然失敗してエラー1009が発生します。問題のコードはタイムライン上にあることもあります。そこにコードを追加する最初の取り組みであり、まだ存在する多くのチュートリアルですコードを配置するタイムラインコードレイヤー。
public class Main extends MovieClip {
public function Main() {
stage.addEventListener(Event.ENTER_FRAME,update); // here
このコードがうまくいかない理由は簡単です。表示オブジェクトは、最初にインスタンス化されてから表示リストに追加され、表示リストの外にある間は、 stage
はnullです。
このようなコードが悪い場合は:
stage.addEventListener(Event.ENTER_FRAME,update); // here
タイムライン上に配置されます。 Main
オブジェクトはGUIを使ってステージングすることができますが、それはしばらくの間も動作します。その後、SWFが別のSWFから読み込まれ、突然コードが破損します。これは、SWFがプレーヤによって直接ロードされ、ロードが非同期に処理されるときに、 Main
のフレームが異なる方法で構築されるために発生します。これを解決するには、 Event.ADDED_TO_STAGE
リスナーを使用し、ステージに対応するすべてのコードを配置し、リスナー自体をタイムラインではなくASファイルに配置します。
タイプキャストが無効です
function listener(e:Event):void {
var m:MovieClip=e.target as MovieClip;
m.x++;
}
このようなリスナーがMovieClip
子孫( Sprite
)ではないオブジェクトにアタッチされているMovieClip
、型キャストは失敗し、その結果の後続の操作は1009エラーをスローします。
インスタンス化されていないオブジェクト
var a:Object;
trace(a); // null
trace(a.b); // Error 1009
ここでは、オブジェクト参照は宣言されていますが、値が割り当てられていません。 new
かnull以外の値が代入されていてもかまいません。そのプロパティまたはメソッドを要求すると、1009のエラーが発生します。
多段階式
x=anObject.aProperty.anotherProperty.getSomething().data;
ここでは、ドットの前にあるオブジェクトはすべてnullになり、複雑なオブジェクトを返すメソッドを使用すると、nullエラーをデバッグするための複雑さが増します。最悪の場合、メソッドがネットワーク上でデータを取得するなど、無関係な障害を起こしやすい場合。
未処理関数の結果
s=this.getChildByName("garbage");
if (s.parent==this) {...}
getChildByName()
は、入力の処理中にエラーが発生した場合にnullを返すことができる多くの関数の1つです。したがって、nullを返す可能性のある関数からオブジェクトを受け取っている場合は、最初にnullをチェックしてください。ここでは、 s
がnullであるかどうか最初にチェックすることなく、プロパティが即座に照会されます。これは1009エラーを生成します。
忘れたイベントリスナー
addEventListener(Event.ENTER_FRAME,moveChild);
function moveChild(e:Event):void {
childMC.x++;
if (childMC.x>1000) {
gotoAndStop(2);
}
}
この例では、設計時にMain
に追加されたchildMC
を移動しchildMC
が、 gotoAndStop()
が呼び出されると直ちに1009をgotoAndStop()
そのchildMC
がフレーム2に存在しない場合)。これの主な理由は、 gotoAndStop()
、 gotoAndPlay()
を使用して、現在のフレームとキーフレームで区切られた宛先フレームを持つか、またはSWFがある場合は通常の再生によって、キーフレーム(前のフレームのオブジェクトセットを継承しないフレーム)現在のフレームの内容が破棄され、GUIから保存されたデータを使用して新しい内容が作成されます。したがって、新しいフレームにchildMC
という名前の子がない場合、プロパティー要求はnullを返し、1009がスローされます。
2つのイベントリスナーを追加して1つだけ削除したり、1つのオブジェクトにリスナーを追加したり、別のオブジェクトからリスナーを削除したりする場合も、同じ原則が適用されます。オブジェクトにそれぞれのイベントリスナーが接続されていない場合、 removeEventListener
呼び出しで警告が表示されないため、イベントリスナーを慎重に追加および削除するコードを読んでください。
注: Timer
オブジェクトを使用すると、 setInterval()
およびsetTimeout()
呼び出すとイベントリスナーも作成されますが、これも適切にクリアする必要があります。
フレームベースのオブジェクトへの無効な参照
gotoAndStop()
は、フレームベースのプロパティを参照するコードの途中で呼び出されることがあります。しかし、 フレームが変更された直後に、現在のフレームに存在していたプロパティへのリンクはすべて無効になります。したがって、それらを含む処理は直ちに終了する必要があります。
このような処理の一般的なシナリオは2つあります。まず、ループはgotoAndStop()
呼び出しの後で終了しません。
for each (bullet in bullets) {
if (player.hitTestObject(bullet)) gotoAndStop("gameOver");
}
ここで1009エラーは、 gotoAndStop()
呼び出しを処理している間にplayer
MCが破壊されたことを意味しますが、ループは継続し、now-nullリンクを参照してhitTestObject()
を取得します。条件がif (bullet.hitTestObject(player))
、エラーは#2007 "パラメータhitTestObjectをnullにすることはできません"となります。解決策は、 gotoAndStop()
呼び出した直後にreturn
文を置くことです。
2番目のケースは、同じイベントの複数のイベントリスナーです。このような:
stage.addEventListener(Event.ENTER_FRAME,func1);
stage.addEventListener(Event.ENTER_FRAME,func2);
function func1(e:Event):void {
if (condition()) {
gotoAndStop(2);
}
}
ここで、 condition()
がtrueの場合、最初のリスナーはgotoAndStop()
を実行しますが、2番目のリスナーはまだ実行され、フレームのオブジェクトを参照すると1009のエラーがスローされます。解決策は、単一のイベントで単一のオブジェクト内の複数のリスナーを回避することです。そのイベントのすべての状況を処理するリスナーを1つ持ち、フレームの変更が必要な場合は適切に終了できます。