« 早朝日記 6/23 | Home | 夏のプリン »

Jun 232004

なんか突然クロージャ

thFlash.gifFlash でクロージャ。[torus solutions!]
想像もしなかった解決法。すごい。無記名を使用しないonEnterframeには基本的に引数を付けれないので(一度の発動で停止)泣く泣く初期化を行う関数を別に作り、その中からonEnterframeへの関数の割り当てとか行っていました。これをreturnで置換(?)できるとは恐るべし。コレ使えばclassのconstractorみたいに初期化情報を引渡しして一括で処理も可能。上記のページでは条件一致の際に発動する関数は固定みたいだけど、その辺も引数で渡して"apply"とか使えば色々流用は可能そうです。(AS2のclassだとそのメソッド自体のundefinedの判定で不正処理を停止とかも可能か?むしろinterface?)onEnterFrame以外にもボタンイベント系のセッティングとかにはかなり重宝しそうです。世の中賢いことを考えてくれる人はいるもんです・・。感謝。
補足だが上記のサイトのサンプルでは

mc.onEnterFrame = null;
と記述されているが、これだと"null"としてメモリに残ってしまうので、
delete mc.onEnterFrame

でやったら終了後は綺麗さっぱりな状態になると思われまふ。

[其の他参考]
クロージャ/MLOG
[1.3 クロージャ] /Effecttive JavaScript - Dynamic Scripting

9 Comments

うあー、これ知らんかった。
書き直したいコードがたくさんある...。

これ色々試したい機能たくさんあるんよねー。
たとえばonEnterframeにローカル変数を設定して継承できるか?とか。これができたらonEnterframeでMCを動かしたりするメソッド周りの変数を全部関数内にクローズできてパッケージとして非常に便利。ボタン系でもstatusの継承と初期化ってのを関数内にパッケージにできるってのは非常に魅力かも。
結局Classベースでのクロージャってことになるのだろうけど、それでも非常に便利なんじゃなかろうか?
後日検証しみまふ。

あー、そうですね、私も基本的にその書き方をしてましたが、ここでいう"count"をdeleteしないといけないのがうざったくて、その辺クロージャってその内部で綺麗に完結して掃除してくれるので結構いいかなあと思って最近使っています。
ただまぁ同時にいくつかの時間処理を使うことが多いのでonEnterFrameとsetIntervalを組み合わせて、onEnterFrameは主に描画系処理、setIntervalは内部変数の処理に割りあてています。
どーもsetIntervalは描画系の処理がonEnterFrameよりももたつく気がするので・・・。

ご紹介どうもー。

結構みんな delete 使ったほうが良いって書いてるんですが、delete できれいさっぱりにしちゃうと、また次に手続きを割り当てるときにそのためにメモリを確保しなくちゃいけないような気がするので、こういうところは敢えて null を代入しています。

また、クロージャとして生成した手続きは、イベントハンドラに null を入れた瞬間にどこからも参照されなくなり、この時点で GC(ガベージコレクション)の対象になるので、メモリのリークにはならないはずです。たぶん。

はじめまして、
>delete できれいさっぱりにしちゃうと、また次に手続きを割り当てるときにそのためにメモリを確保しなくちゃいけないような気がするので、こういうところは敢えて null を代入しています。
これは違うところでクロージャ設定しても同じメモリを使用するってことなんでしょうか?それともそのタイムライン上のonEnterFrameってことです?
あまりメモリ関係は詳しくないのですが、もう一度メモリを確保するという行為は危険なんでしょうか?
何故何故クンになってしまいました・・・。

あ、いや、べつに危険でもなんでもないし、単に好みの問題です。
delete しちゃうと「onEnterFrame に値が割り当てられているかどうか」というフラグが変わってしまうので、というかそんな気がするので、なんとなくそれがいやかなぁっていうか……。

> もう一度メモリを確保するという行為は危険なんでしょうか?
というか、delete しなくてもメモリは開放されます。それが GC というやつの働きです。
C 言語のようにメモリ管理を完全にプログラマがやらないといけない言語に比べて、ActionScript は基本的に全部 GC まかせにできるので、わざわざプログラマが明示的に delete なんて書くのはちょっとダサいかなっていう主観的な話でした(笑)。

お返事ありがとうございました。
>delete しなくてもメモリは開放されます。それが GC というやつの働きです。
この辺デザイン上がりなのであまり詳しくはないのですけど、
this.onEnterFrame = null;
とした場合Flashのデバッガ上では
onEnterFrame :null
として表示されているのが私はそれが気持ち悪くって
delete this.onEnterFrame
としていたりします。(別にif(!this.onEnterFrame)でどちらも判定できるのでそんなにこだわりはないのですが)
これデバッガ上に表示されているということはメモリが消費されているということではないんでしょうか?

あ、なんか話がはじめに戻っちゃいましたが、null 1 個分のメモリはとられています。開放されるといったのは、クロージャのために割り当てられたメモリのことでした。
ぼくは逆に、この onEnterFrame プロパティの存在そのもの(厳密にいうとシンボルテーブル(プロパティの一覧表みたいなもの)のエントリ)がなくなってしまうのがもったいないので、delete はしないっていうだけです。ここは完全に主観的な問題ですね。

あ、なるほど。
昔VCとかの画面を見たときにそれぞれのパーツに全部そういうのがすでに定義されているダイアログを見たような気がします。
色々お答えいただきましてありがとうございました。

Leave a comment

Search and Archives