[AS](MCの)参照渡しと、配列への格納への違い

メモリ管理でつまづいている、ちょっと挙動がわからない。

やりたいことはこんな感じ。

var mc0:MovieClip = new MovieClip();
addChild(mc0);
var array:Array = []
array.push(mc0);
var mc1 = array[0]

//↓で表示リストから消えるのは無問題
removeChild(mc1);
//↓だとmc0分のメモリは消えないっぽい。
mc1=null;
//↓だとmc0分のメモリは消えるっぽい。
array[0] = null;

参照先を操作すれば、表示リストからは消せる。
でも、メモリを開放できないのがなんだか気持ち悪い。
参照で渡した場合、参照先をnullにしても、参照元はnullにならないってこと?
配列に格納するのも参照渡しと同じ感覚だと思っていたけど、違うってこと?
このあたりは今度えらい先生と会う機会があるときに教えてもらおう・・・

[追記]
コメントにて教えて頂きました。
参照で渡した場合、参照先をnullにしても、参照元はnullにならない、でOK。
参照先との関係が切れるだけ、ということだそうです。

[AS]overrideする場合は、元の関数とパラメータを同じにすること

関数をoverrideする場合は、元の関数とパラメータを全て同じにする必要があるらしい。
以前、インターフェースでは戻り値必須という記事を書いたけど、overrideもそんな感じらしい。

↓この関数をoverrideするには・・・

protected function testFunc(){}

↓こんな感じになる。

protected override function testFunc(){}
//↓これだとNG(voidがあるから)
//protected override function testFunc():void{}

またこういう場合は、

protected function testFunc():void{}

こんな感じ

protected override function testFunc():void{}
//↓これだとNG(voidがないから)
//protected override function testFunc(){}

注意が必要なのは、戻り値のvoid。
あってもなくても意味一緒じゃね?と思ってもFlash上では一緒とは判断してくれない模様。
正確にコーディングしないと。。。

参考サイト
desginのFlash:[エラー!!][AS3]1023: オーバーライドに対応していません。

[AS]Flickrの画像のBitmapDataを弄る際のセキュリティ解除方法

Flickrの画像を読み込み、bimapdataを弄ろうとすると、以下のように怒られる。

SecurityError: Error #2122: セキュリティサンドボックス侵害 : BitmapData.draw:http://393.bz/test/New.swf は http://farm4.static.flickr.com/3315/3667944681_06e506542e.jpg にアクセスできません。ポリシーファイルが必要ですが、このメディアがロードされたとき、checkPolicyFile フラグが設定されませんでした。
at flash.display::BitmapData/draw()
at NewClass/drawImage()

以下のおまじないを記述すれば大丈夫。

Security.loadPolicyFile("http://api.flickr.com/crossdomain.xml");
Security.loadPolicyFile("http://farm1.static.flickr.com/crossdomain.xml");
Security.loadPolicyFile("http://farm2.static.flickr.com/crossdomain.xml");
Security.loadPolicyFile("http://farm3.static.flickr.com/crossdomain.xml");
Security.loadPolicyFile("http://farm4.static.flickr.com/crossdomain.xml");

[AS]配列の中身全部をtraceする

toString()で楽勝でした。

var num:Number = 100;
var array:Array = ["a","b","c",num]
trace(array.toString()) //出力:a,b,c,100

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(8)
-カプセル化

カプセル化とは、
1.パブリックなプロパティは使わない
2.外部クラスのオブジェクトを参照しない。(そのクラスの引数を経由した参照は除く)

よくわからんけど、プロパティ値を変更するときは直接変更できないようにして(privateにする)、
パブリックなメソッドを用意してそれを使って内部のプロパティを変更するような仕組みを作るといいらしい。
2.については引数を使わずに外部クラスを参照する方法が浮かばないのだが。

[FD]{の前の改行位置を自分流に変更する

FlashDevelopだと自動で生成してくれる構文が、デフォルトだと、{前に改行される。
こんな感じ

package  
{
	public class ClockData 
	{
		public function ClockData() 
		{
			
		}
	}
}

まぁ好みの問題で、{前は改行してくれない方が良いという場合。
(いわゆる私の場合)
これは設定ファイルを書き換えればコントロール可能。
Tool→ApplicationFilesで開いたフォルダ内のファイルを弄る。
たとえば、Templatesフォルダ内のProject→AS3Project内のClass.as.fdtを開いてみると、改行が入る場所に、
$(CSLB)という文字列があるのでこれを削除すれば改行されなくなる。
ほかにも適宜ファイルの$(CSLB)を消せば改行部分を削除可能。

※一点だけ、わかりにくかった場所・・・
ctrl+shift+1で生成させる部分の改行設定は、
Data→ASCompletion→Generator.txtにて設定可能。

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(7)
-プロキシパターン

プログラムのタスク処理における一般的なやりかた。
他のオブジェクトへのアクセスを提供するためのクラス。
(他のオブジェクト:AS、img、xml、flv、FMS等)
最初にオブジェクトを全部作ってしまうのではなく、必要なときに作ろうという考え方。

仮想プロキシとリモートプロキシの2種類ある。

仮想プロキシ
Loaderクラスがまさにそれ。
プロキシという考え方があるから、画像を読み込みの際、読み込みが完了する前にLoaderのプロパティとか変更できるということらしい。

こんな感じか

//インスタンス生成
var loader:Loader = new Loader();
//loaderインスタンスにはまだ中身は無いけどプロパティとか設定しておく
loader.x = 100;
loader.y = 200;
loader.alpha = 0.5;
//表示リストに追加しちゃっておいても良い
this.addChild(loader);
//そして以下、欲しいときにload()メソッドを実行すればいい、みたいな感じ?

他に仮想プロキシの役割として、ゆるいシリアル化
ゆるいシリアル化の例(XMLの項目を
→硬いシリアル化:xmlを最初に全部要素、属性ごとに配列とかに割り振っちゃう
→ゆるいシリアル化:必要なときに応じて、都度xmlを取り出して使う

リモートプロキシ
対象がネットワーク先になるような感じ。
たとえばflikrAPIをたたいてAPIのメソッドに従った画像ひっぱってくるときの場合、みたいな

[AS]インターフェイスで関数を定義する際、および実装する際は戻り値が必須

インターフェイスで関数を定義する際は戻り値が必須らしい。
(戻り値がない場合も必ずvoidを書かないと駄目っぽい)

たとえばこれだとエラーになった。

package  {
	public interface TestInterface {
		
		//↓戻り値のvoidを省略すると駄目っぽい
		function testFunc1();
		//↓これはOK
		function testFunc2():void;
		function testFunc3():Boolean;
	}
}

また実装の際にもInterfaceで定義された関数を記述する際もvoidの記述が必須。
(省略したらエラーになった)

たとえばこんな感じ。

package  {
	public class Jissou implements TestInterface{
		
		public function Jissou() {
			
		}
		//↓voidを省略するとエラー
		public function testFunc1() {
			trace("testFunc1");
		}
		//これならOK
		public function testFunc2():void {
			trace("testFunc2");
		}
		public function testFunc3():Boolean {
			var bol:Boolean = false;
			return bol;
		}
	}
}

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(6)
-テンプレートメソッドパターン

テンプレートメソッドとは、
汎用性のあるアルゴリズムを抽象メソッド(中身の無い定義だけのもの)として記述したもので、抽象クラス(インスタンス化を目的としない)内で定義される。
アルゴリズムの中身の具体的な定義は抽象メソッドをオーバーライドするときに定義する。
アルゴリズムの構造はテンプレートメソッドに保持される。

(後で)生成されるサブクラスで詳細を定義するような、”汎用的なアルゴリズム”を定義したいときに使う。
抽象クラスのひとつの使い方って感じなのかな?

テンプレートメソッドが記述されたクラスの例

package  {
	public class AbstractGame {
		//インスタンス化を必要としないので、コンストラクタはいらない
		public function AbstractGame() {
		}
		
		//(finalメソッドは他のクラスからoverrideできない)
		//init()がテンプレートメソッドとなる
		public final function init(){
			createField()
			createTeam("red");
			createTeam("blue");
			startGame();
		}
		
		//直接実行した場合はエラーを投げる
		public function startGame():void{
			throw new Error("Abstract Method!");
		}
		//直接実行した場合はエラーを投げる
		public function createTeam(name:String):void{
			throw new Error("Abstract Method!");
		}
		//直接実行した場合はエラーを投げる
		public function createField():void{
			throw new Error("Abstract Method!");
		}
	}
}

テンプレートメソッドを利用するクラスの例

package  {
	//テンプレートメソッドを含んだクラスを継承
	public class FootballGame extends AbstractGame {
		
		public function FootballGame() {
		}
		
		//AbstractGameクラス内のメソッドをオーバーライド
		public override function  createField():void {
			trace("Create Field");
			//ここに具体的な処理を書く
		}
		public override function  createTeam(name:String):void {
			trace("Create Team");
			//ここに具体的な処理を書く
		}
		public override function  startGame():void {
			trace("start Game");
			//ここに具体的な処理を書く
		}
	}
}

これらを利用するためのドキュメントクラス

package  {
	import flash.display.Sprite;
	
	public class FactoryExample extends Sprite{
		
		public function FactoryExample() {
			//テンプレートメソッドのサブクラスのインスタンスを作る
			var game:FootballGame = new FootballGame();
			//サブクラスから、スーパークラスのメソッド(init())を実行する。
			game.init();
		}
	}
}

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(5)
-シングルトンパターン

シングルトンのルール
・(シングルトンインスタンスは)プライベートなstaticなプロパティに保持
・(シングルトンインスタンスに)アクセスするにはパブリックなメソッドを使う。(インスタンスが無い場合は生成)

汎用的なシングルトンパターン

package  {
	public class Singleton {
		
		//Singletonインスタンスを保持
		static private var _instance:Settings;
		
		//他のオブジェクトからnew Singleton()では作らせないようにする
		public function Singleton(enforcer:SingletonEnforcer) {
		}
		
		//インスタンス作成はこのメソッドで
		public function getInstance():Settings {
			//一回目はインスタンスを作る
			if (Settings._instance == null){
				Settings._instance = new Settings(new SingletonEnforcer));
				
			}
			//保持しているインスタンスを返す
			return Settings._instance;
		}
	}
}
//new Singletonさせないためのクラス
class SingletonEnforcer{}