Dictionay クラス (livedocs@lab) は beta2 から追加されたクラスで、オブジェクトをキーとして値を管理することができます。Object を使っても同じように連想配列を実現できますが、Dictionary ではいわゆる"弱い参照"が使えます。
また、Object では文字列がキーとして扱われるため toString() の値が同じオブジェクトは全て同じキーとして扱われますが、Dictionary では別々のオブジェクトであれば toString() の値に関わらず異なるキーとして扱われます。
具体的な例を見てみましょう。下の例では key1 と key2 という2つのオブジェクトが同じ文字列に変換されるように設定しています。
// まず2つのキーを生成 var key1:Object = new Object(); var key2:Object = new Object(); key1.toString = function():String { return "key"; }; key2.toString = function():String { return "key"; }; // 値のオブジェクトを生成 var myVal:Object = "my value"; // Object の場合 var myKey:Object = new Object(); myObj[key1] = myVal; trace(myObj[key2]); // my value が出力される // Dictionary の場合 var myDict:Dictionary = new Dictionary(); myDict[key1] = myVal; trace(myDict[key2]); // undefined が出力される
Object の場合には key1 をキーとして代入した値を key2 で取得できますが、Dictionary の場合には key1 をキーとする値は key1 でしか取り出すことができません。
ところで、beta 2 では Flex Builder 2 のバグのため Dictionary クラス型が参照できません。そのため上記のコードはコンパイルできません...現時点では、このような場合のための(?)getClassByName() メソッドを使用してインスタンスを作成する必要があります。
// beta 2 のバグを回避 var dictionaryCls:Class = getClassByName("flash.util.Dictionary"); var myDict:* = new dictionaryCls(); // 本来はこちらの宣言でインスタンスを生成する //var myDict:Dictionary = new Dictionary(); myDict[key1] = myVal; trace(myDict[key2]); // undefined が出力される
さて、Dictionary の登録を削除するときは以下の方法が使用できます。それぞれ、値のみを削除する場合とエントリーを削除する場合です。
// 値オブジェクトへの参照を削除 myDict[key1] = null; trace(myDict[key1]); // null が出力される // myDict からエントリーを削除 delete myDict[key1]; trace(myDict[key1]); // undefined が出力される
弱い参照の使用
弱い参照とは、たとえ参照があってもガーベッジコレクションの対象となる種類の参照です。キャッシュなど"とりあえず置いておく"タイプのオブジェクトを管理するときなどに便利です。
Dictionary クラスは弱い参照を利用した weak-key と呼ばれるタイプのディクショナリーとして使うことができます。weak-key ディクショナリーでは、キーとして使われているオブジェクトへの参照が弱い参照になっています。そのため、キーオブジェクトへの参照が Dictionary からのみだと、ガーベッジコレクションのタイミングでキーオブジェクトが削除され、併せて Dictionary 内の該当するエントリが削除されます。
Dictionary クラスを weak-key ディクショナリーとして使うには、コンストラクタの引数に true を指定します。デフォルトは false になっています。
// beta 2 のバグを回避 var dictionaryCls:Class = getClassByName("flash.util.Dictionary"); var myDict:* = new dictionaryCls(true); // 本来はこちらの宣言でインスタンスを生成する //var myDict:Dictionary = new Dictionary(true); // 後の使い方は Object とほぼ同じ var myKey:Object = new Object(); var myVal:Object = new Object(); myDict[myKey] = myVal;
上の例で myKey が myDict からのみの参照であれば myKey はガーベッジコレクションの対象になります。
コメントする