Показать сообщение отдельно
Старый 13.10.2006, 12:29
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 40  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 46. Мягкие ссылки

В ActionScript 3 есть две возможности поставить мягкую ссылку (Weak Reference) на объект, которая не будет учитываться счетчиком ссылок.
1. При использовании класса Dictionary его конструктору можно передать параметр true, чтобы использовались мягкие ссылки на объекты.
Код:
var dict:Dictionary = new Dictionary(true); // использовать мягкие ссылки
В этом случае Dictionary в качестве ключей будет использовать мягкие ссылки на объекты, которые не учитываются счетчиком ссылок и не мешают удалению объектов из памяти.
Код:
var obj:Object = new Object();
dict[obj] = true;
delete obj; // сборщик мусора удалит объект obj, поскольку ссылка на него из dict мягкая
2. Можно добавить слушатель события с мягкой ссылкой. У addEventListener последний параметр указывает, использовать мягкую ссылку или обычную (по умолчанию). При использовании мягкой ссылки, не удаленный обработчик события не помешает удалению объекта из памяти.
Код:
// addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
addEventListener(MouseEvent.CLICK, clickHandler, false, 0 true); // использовать мягкую ссылку
MerlinTwi: Для понимания мягкой ссылки в addEventListener, рассмотрим случай из предыдущего примера. Используем мягкую ссылку при создании слушателя события enterFrame:
Код:
init();

function init():void {
	var test:Sprite = new Sprite();
	test.addEventListener(Event.ENTER_FRAME, handle, false,0,true);
}

function handle(e:Event):void {
	trace("enterFrame");
}
Теоретически сборщик мусора должен удалить спрайт, т.к. на него не остается ссылок из переменных, из root он недоступен, и обработчик события enterFrame стоит мягкий. Вот только когда сработает сборщик мусора, решает flash-плеер сам… через секунду, через час, день? И до тех пор, пока сборщик мусора не удалит спрайт из памяти, функция handle будет исправно срабатывать каждый фрейм.
Экспериментально был найден способ заставить сборщик мусора сработать немедленно, нужно создать много объектов для которых потребуется выделение большого куска памяти. Подтолкнем таким способом сборщик мусора сработать по клику мышки:
Код:
init();
addEventListener(MouseEvent.CLICK, immediatelyGC);

function init():void {
	var test:Sprite = new Sprite();
	test.addEventListener(Event.ENTER_FRAME, handle, false,0,true);
}

function handle(e:Event):void {
	trace("enterFrame");
}

function immediatelyGC(e:Event):void {
	trace("run GC");
	var ar:Array = new Array();
	for (var i:int=0; i<100000; i++) {
		ar.push( new Object() );
	}
}
В трейсе будет:
. . .
enterFrame
enterFrame
enterFrame
run GC

После клика мышки и запуска функции immediatelyGC, сборщик мусора удалил спрайт из памяти и более функция handle не вызывается.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.