2009年8月18日火曜日

配列を複製する

配列の内容をコピーしたいと思い、以下のように記述すると、参照している配列は同じなので、新しい配列(の参照)に記述した内容が、元の配列にも影響してしまう。

var arr1:Array = ['a','b','c','d','e'];
var arr2:Array = arr1;
trace('arr1 : ' + arr1.length); // arr1 : 5
trace('arr2 : ' + arr2.length); // arr2 : 5
arr2.shift();
trace('arr1 : ' + arr1.length); // arr1 : 4
trace('arr2 : ' + arr2.length); // arr2 : 4

Array クラスの slice 関数は、指定したインデックス間を抜き出して新しい配列を作ってくれる。インデックスを省略すると、開始から終了まで全ての値を抜き出してくれるので、これでOK。

var arr1:Array = ['a','b','c','d','e'];
var arr2:Array = arr1.slice();
trace('arr1 : ' + arr1.length); // arr1 : 5
trace('arr2 : ' + arr2.length); // arr2 : 5
arr2.shift();
trace('arr1 : ' + arr1.length); // arr1 : 5
trace('arr2 : ' + arr2.length); // arr2 : 4

イベントの解放は大事

インスタンスに追加したイベントは、そのインスタンスを参照する変数が別のインスタンスを参照するようになっても、しっかりその役割を果たし続ける。えらいえらい。 使い終わったらしっかり removeEventListener してあげるのが大事。
var tim:Timer;

tim = new Timer(1000,2);
tim.addEventListener(TimerEvent.TIMER, timerHandler1);
function timerHandler1(e:TimerEvent):void { trace('>>> timer1'); }
tim.start();

tim = new Timer(1000,2);
tim.addEventListener(TimerEvent.TIMER, timerHandler2);
function timerHandler2(e:TimerEvent):void { trace('>>> timer2'); }
tim.start();

// >>> timer1
// >>> timer2
// >>> timer1
// >>> timer2

コンテキストメニューの拡大とか縮小とかを非表示

var mc:MovieClip = new MovieClip();
var menu:ContextMenu = new ContextMenu();
menu.hideBuiltInItems();
mc.contextMenu = menu;

contextMenu は、InteractiveObject のプロパティだけども、同クラスを継承する Stage クラスでは、参照はできても設定はできないため(read-only)、IllegalOperationError がスローされます。ContextMenu のカスタマイズもできないことだし、もう Stage に DisplayObject を配置する理由はなくなった気がする。

一応、Stage クラスにて同様の効果を得たい場合は、showDefaultContextMenu を利用すればすっきり。

stage.showDefaultContextMenu = false;