まず、”name”, “birth”, “part”というプロパティを持つオブジェクトを生成し、それぞれのプロパティに値を入れる。
var obj1:Object = new Object(); obj1.name = "John"; obj1.birth = 1940; obj1.part = "guitar"; trace(obj1.name); //出力:John
次に、このオブジェクトのコピーを作成し、一部のプロパティを変更するために、以下のスクリプトを実行する。
var obj2:Object = obj1; obj2.name = "George"; obj2.birth = 1943; trace(obj1.name, obj2.name); //出力:George George
すると、コピー先(obj2)だけでなく、コピー元(obj1)のプロパティまでも変更されてしまっている。
これは、obj2 = obj1; としたとき、obj1をコピーしているのではなく、obj1への参照を作成しているにすぎないためである。
・・・というのは実は配列でも同じ事がおこる。で、配列の場合はArray.sliceメソッドを使う事でコピーを作る事ができる(参考:TONPOOBLOG » 配列の(浅い)コピー)んだけど、オブジェクトのコピーを作る時はどうするか?
これまではfor…inを使ってプロパティをコピーしていました。
var obj2:Object = new Object();
for (var name:String in obj1) {
obj2[name] = obj1[name];
}
obj2.name = "George";
obj2.birth = 1943;
trace(obj1.name, obj2.name); //出力:John George
ところが、flash-jpの以下のスレッドでByteArrayクラスというのがあることを発見。
FLASH-JP.COM – フォーラム Re: SharedObjectで任意のデータを保存したい
早速ヘルプを参照。
ByteArray – ActionScript 3.0 コンポーネントリファレンスガイド
よくわからないけど、こういうことかな?
//ByteArrayインスタンスを生成 var myByteArray:ByteArray = new ByteArray(); //コピー元ObjectのバイナリデータをByteArrayインスタンスに書き込み myByteArray.writeObject(obj1); //ByteArrayインスタンスのデータをコピー先Objectに読み込み var obj2:Object = myByteArray.readObject();
と思ったら、以下のエラーが。
Error: Error #2030: ファイルの終端 (EOF) が検出されました。
at flash.utils::ByteArray/readObject()
at Sample()
どうやら、先のflash-jpのnekoyukiさんの投稿にもあったように、一度ByteArray.compress→ByteArray.uncompressしないとダメなようですね。
わざわざ圧縮→解凍などという手間をかけずとも、ByteArray.positionプロパティの値を0にし、ByteArrayのファイルポインタの位置を先頭に戻すことで対応できました!(flash-jpのスレッドでの野中先生のレスから判明しました。野中先生ありがとうございます!)
//ByteArrayインスタンスを生成 var myByteArray:ByteArray = new ByteArray(); //コピー元ObjectのバイナリデータをByteArrayインスタンスに書き込み myByteArray.writeObject(obj1); //ByteArrayのファイルポインタの位置を先頭に移す myByteArray.position = 0; //ByteArrayインスタンスのデータをコピー先Objectに読み込み var obj2:Object = myByteArray.readObject(); trace(obj2.name, obj2.birth, obj2.part); //出力:John 1940 guitar
となると、同じくflash-jpのnekoyukiさんの書いたように、メソッドにしてしまったほうが楽そうです。配列のコピーにも使えますしね。ということでできあがったサンプル用のドキュメントクラス(Sample.as)は以下の通り。
package {
import flash.display.MovieClip;
import flash.utils.ByteArray;
public class Sample extends MovieClip{
public function Sample() {
var obj1:Object = new Object();
obj1.name = "John";
obj1.birth = 1940;
obj1.part = "guitar";
var obj2:Object = byteCopy(obj1);
obj2.name = "George";
obj2.birth = 1942;
trace(obj1.name, obj2.name); //出力:John George
var array1:Array = ["John", "Paul", "George", "Ringo"];
var array2:Array = byteCopy(array1);
array2[3] = "Stuart";
trace(array1); //出力:John,Paul,George,Ringo
trace(array2); //出力:John,Paul,George,Stuart
}
//バイナリデータのコピーメソッド
public function byteCopy(objFrom:*):*{
//ByteArrayインスタンスを生成
var myByteArray:ByteArray = new ByteArray();
//コピー元ObjectのバイナリデータをByteArrayインスタンスに書き込み
myByteArray.writeObject(objFrom);
//ByteArrayのファイルポインタの位置を先頭に移す
myByteArray.position = 0;
//ByteArrayインスタンスのデータを返す
return myByteArray.readObject();
}
}
}

コメントはまだありません »
コメントはまだありません。
この投稿へのコメントの RSS フィード。 TrackBack URL
コメントする