クラスメソッドでの参照がガーベジコレクション対象になる

by kura07
弱参照で Dictionary インスタンスを作ると、
クラスメソッドでの参照がガーベジコレクション対象になってしまう

private function a():void { } ← ガーベジコレクションされる(どうして?)
private const b:Function = function():void { } ← ガーベジコレクションされない(思った通り)
♥0 | Line 49 | Modified 2012-11-08 08:13:22 | MIT License
play

ActionScript3 source code

/**
 * Copyright kura07 ( http://wonderfl.net/user/kura07 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hMTq
 */

/**
 * 弱参照で Dictionary インスタンスを作ると、
 * クラスメソッドでの参照がガーベジコレクション対象になってしまう
 * 
 * private function a():void { } ← ガーベジコレクションされる(どうして?)
 * private const b:Function = function():void { } ← ガーベジコレクションされない(思った通り)
 */
package {
    
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.TimerEvent;
    import flash.text.TextField;
    import flash.utils.Dictionary;
    import flash.utils.Timer;
    
    [SWF(width = 465, height = 465, frameRate = 30, backgroundColor = 0xffffff)]
    
    public class DictionaryTest extends Sprite {
        
        private var _dictionary:Dictionary;
        private var _tf:TextField;
        private var _timer:Timer;
        
        //================================
        private function a():void { } // クラスメソッド
        private const b:Function = function():void { } // 関数
        //================================
        
        public function DictionaryTest() {
            
            // 弱参照でDictionary インスタンスを作成。
            // (強参照だと両者ともガーベジコレクションの対象とはならない)
            _dictionary = new Dictionary(true);
            addChild(_tf = new TextField); _tf.width = _tf.height = 465;
            
            //================================
            _dictionary[a] = "exist!"; // クラスメソッドによる参照
            _dictionary[b] = "exist!"; // 関数による参照
            //================================
            _check();
            
            _timer = new Timer(1000, 4);
            _timer.addEventListener(TimerEvent.TIMER, _gc);
            _timer.addEventListener(TimerEvent.TIMER, _check);
            _timer.start();
            
        }
        
        /**
         * ガーベジコレクションを多分実行させる
         */
        private function _gc(e:TimerEvent):void {
            
            var ary:/*BitmapData*/Array = [], i:uint;
            try {
                for (i = 0; i < 100; i++) ary[i] = new BitmapData(1000, 1000);
            }
            catch (e:Error) { }
            
            while (ary.length) ary.pop().dispose();
            
        }
        
        /**
         * _dictionary の中身をチェックする
         */
        private var _times:uint = 0;
        private function _check(e:TimerEvent = null):void {
            
            _appendText(++_times + "::");
            
            //================================
            _appendText("a: " + _dictionary[a]); // クラスメソッドによる参照
            _appendText("b: " + _dictionary[b]); // 関数による参照
            //================================
            
            _appendText("-------------");
            
        }
        
        
        
        /**
         * 画面にテキストを表示する
         */
        private const _texts:/*String*/Array = [];
        private function _appendText(text:String):void {
            
            _texts.push(text); //if (_texts.length > 20)_texts.shift();
            _tf.text = _texts.join("\n");
            
        }
        
    }

}