Показать сообщение отдельно
Старый 12.03.2009, 02:51
s8000_1 вне форума Посмотреть профиль Отправить личное сообщение для s8000_1 Найти все сообщения от s8000_1
  № 20  
Ответить с цитированием
s8000_1
 
Аватар для s8000_1

Регистрация: Jun 2007
Сообщений: 374
Цитата:
Сообщение от iflamberg
флеш не настолько умный. Все ссылки лучше занулять(включая удаляемых детей).
Неверно. Флэш умный.

Цитата:
Сообщение от 2K WebStudio
есть ли необходимость удалять всех детей
Нет такой необходимости.

Цитата:
Сообщение от __etc
Удаление детей должен произвести сам удаляемый объект.
Разве? Я ни в одном примере не видел, чтобы в каждом классе писались деструкторы, удаляющие всех детей объекта, на который нигде не осталось ссылок. Если у объекта там что-то внутри друг на друга ссылается, оно все будет удалено пачкой.

Цитата:
Сообщение от iflamberg
в общем случае, я делаю метод destroy, который запускает destroy у всех детей, а потом зануляет свои ссылки
Смысл? Эта работа бесполезна Как уже сказали выше, такой подход может ускорить GC, и все.

Цитата:
Сообщение от iflamberg
Непонимаю в чем проблемы, любой программист, который учился программированию на cpp или даже pascal имеет понимание о том, как освободить память.
Так AS3 не паскаль или cpp. В AS3 есть сборщик мусора как бы.


В общем-то проверьте профайлером:

Код AS3:
package{
	import flash.display.*;
	import flash.events.*;
	public class Test extends Sprite{
		var mcs:Array;
		function Test(){
			graphics.beginFill(0xFF00FF);
			graphics.drawRect(0,0,50, 50);
			mcs = new Array();
			var mc:Sprite;
			for (var i:uint = 0; i< 100; i++){
				mc = new Sprite();
				mc.addEventListener(MouseEvent.CLICK, onChildClick);
				mcs.push(mc);
			}
		}
		private function onChildClick(e:Event):void{
			trace (e.currentTarget);
		}
	}
}
Код AS3:
package {
	import flash.display.*;
	import flash.events.*;
	public class MemoryTest extends Sprite {
		var bt:Sprite;
		var bt1:Sprite;
		var mc:Sprite;
		function MemoryTest() {
 
			bt = new Sprite();
			bt.graphics.beginFill(0);
			bt.graphics.drawRect(0,0,100,100);
			stage.addChild(bt);
 
			bt1 = new Sprite();
			bt1.graphics.beginFill(0xFF0000);
			bt1.graphics.drawRect(0,0, 100,100);
			bt1.x = 100;
			stage.addChild(bt1);
 
			bt.addEventListener(MouseEvent.CLICK, createObjects);
			bt1.addEventListener(MouseEvent.CLICK, removeObjects);
 
		}
		function createObjects(e:Event):void {
			if (mc) {
				return;
			}
			mc = new Test();
			mc.addEventListener(MouseEvent.CLICK, clickListener);
			mc.y = 100;
			stage.addChild(mc);
		}
		function removeObjects(e:Event):void {
			if (!mc) {
				return;
			}
			stage.removeChild(mc);
			mc = null;
		}
		function clickListener(e:Event):void{
		}
	}
}
Все прекрасно удаляется из памяти и без ручного обнуления всего и вся. Утечек памяти нет. Версия плеера 10.12.36.

Насчет удаления слушателей надо понимать лишь, что такое слушатель, и как оно работает. А работает оно как-то так:
http://www.javaworld.com/javaworld/j...04-events.html
child.addEventListener(event, parentFunc) в массив _listeners ребенка кладет ссылку на parentFunc. А т. к. это дело изолировано в ребенке, то ничего казалось бы не помешает флэшу удалить спокойно child из памяти, если на него не осталось ссылок. Но из-за особенности флэшовских событий (bubbling) в родителе тоже возможно сохраняются ссылки на ребенка - мое предположение. Поэтому:
Цитата:
Сообщение от __etc
Если родитель слушает события детей, то он должен от детей отписаться.
Хотя ИМХО это банально перестраховка (см. пример для профайлера выше), ибо по-хорошему методы addChild и removeChild класса DisplayObject должны быть умными и удалять всех лишних слушателей из Event Flow автоматически. Может быть в прошлых версиях плеера был какой-то баг, связанный с удалением объектов? __etc, почему именно-то Вы везде рекомендуете удалять слушателей?

Кстати, может кто знает, нет ли где-нибудь статьи, в которой описана модель событий флэша на очень детальном уровне? Т. е. фактически как написать класс EventDispatcher идентичный флэшовому.


Последний раз редактировалось s8000_1; 12.03.2009 в 06:00.