Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 08.09.2006, 15:51
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 1  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

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

Такой пример, создаем мувик, ему добавляем обработку события ENTER_FRAME, по которому просто делаем trace и добавляем возможность по клику удалить этот мувик. Примерно так:
Код:
package {
	import flash.display.Sprite;
	import flash.events.*;

	dynamic public class Test extends Sprite {

		function Test():void {
			addEventListener(Event.ENTER_FRAME, doEnterFrame);
			addEventListener(MouseEvent.CLICK, doClick);
		}

		function doEnterFrame(e:Event):void {
			trace(e);
		}

		function doClick(e:Event):void {
			parent.removeChild(this);
		}
	}
}
Так вот, после клика и исчезновения мувика, продолжает вызываться doEnterFrame! Хотя событие было привязано к мувиклипу, которого уже якобы нет. На самом деле, этот мувик garbage collector не удаляет, т.к. на него осталось зарегистрировано событие.
Собственно если внимательно прочитать Help по addEventListener, там об этом четко говорится.
Цитата:
You should remove an event listener when it is no longer needed by calling EventDispatcher.removeEventListener(). Failure to remove unnecessary event listeners may have a negative impact on memory usage. Any objects with registered event listeners are not removed from memory because the garbage collector does not remove objects that still have references.
По-русски, обязательно удалять все обработчики событий (removeEventListener), когда они более не нужны, иначе объект продолжает болтаться в памяти!
Подобное положение дел, лично меня совсем не радует. Т.е. в каждом классе, который обрабатывает любые события, нужно добавлять две функции open() для инициализации обработчков событий и close() для их удаления, которую нужно вызывать перед удалением этого класса. Т.е. просто removeChild уже не достаточно. Или же в каждом классе самому следить за событием removed, по которому удалять все обработчики за собой. Примерно так:
Код:
package {
	import flash.display.Sprite;
	import flash.events.*;

	dynamic public class Test extends Sprite {

		function Test():void {
			addEventListener(Event.REMOVED, onRemoved);
			addEventListener(Event.ENTER_FRAME, doEnterFrame);
			addEventListener(MouseEvent.CLICK, doClick);
		}
		
		function onRemoved(e:Event):void {
			trace("onRemoved");
			removeEventListener(Event.REMOVED, onRemoved);
			removeEventListener(Event.ENTER_FRAME, doEnterFrame);
			removeEventListener(MouseEvent.CLICK, doClick);
		}

		function doEnterFrame(e:Event):void {
			trace(e);
		}

		function doClick(e:Event):void {
			parent.removeChild(this);
		}
	}
}
Что не совсем верно, т.к. удаление из списка отображаемых объектов еще не означает, что этот объект собираются полностью удалить. Да и сколько получается лишней писанины! Хотелось бы более простого решения, чтобы назначенные обработчики событий не препятствовали удалению объекта.
У функции addEventListener последним параметром идет
Цитата:
useWeakReference:Boolean (default = false) — Determines whether the reference to the listener is strong or weak. A strong reference (the default) prevents your listener from being garbage collected. A weak reference does not. The default value of this parameter is false.
Как я понял, именно то что надо, т.е. если вызвать
Код:
addEventListener(Event.ENTER_FRAME, doEnterFrame, false,0,true);
то объект должен удалиться даже без явного удаления этого обработчика события. Однако, это не работает
Собственно вот, подскажите где я что неправильно понял...
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 08.09.2006, 15:58
Nirth вне форума Посмотреть профиль Отправить личное сообщение для Nirth Посетить домашнюю страницу Nirth Найти все сообщения от Nirth
  № 2  
Ответить с цитированием
Nirth
4AM Games
 
Аватар для Nirth

блогер
Регистрация: Nov 2002
Адрес: Sofia
Сообщений: 6,264
Записей в блоге: 1
Отправить сообщение для Nirth с помощью ICQ Отправить сообщение для Nirth с помощью AIM Отправить сообщение для Nirth с помощью MSN Отправить сообщение для Nirth с помощью Yahoo Отправить сообщение для Nirth с помощью Skype™
removeChild не удаляет экземпляр класса DisplayObject или его наследника, а просто убирает его из контейнера. клип все еще существует, и события все еще работают.
__________________
Я перестал переписывать, начал редактировать, еще лет 15 и я стану писателем ^_^

Старый 08.09.2006, 16:02
miramax вне форума Посмотреть профиль Отправить личное сообщение для miramax Посетить домашнюю страницу miramax Найти все сообщения от miramax
  № 3  
Ответить с цитированием
miramax
 
Аватар для miramax

Регистрация: Oct 2005
Адрес: Борисоглебск
Сообщений: 1,702
Отправить сообщение для miramax с помощью ICQ Отправить сообщение для miramax с помощью AIM Отправить сообщение для miramax с помощью MSN Отправить сообщение для miramax с помощью Yahoo Отправить сообщение для miramax с помощью Skype™
Да с этим я тоже не разобрался... А ещё если в объекте использовать setInterval. То после удаления объекта, "интервал" продолжает вызывать функцию. И ругается что не может её найти, потому что объета не сущетсвует.
Приходится каждый раз писать обработчик события removed, что бы убить все интервалы и листенеры.
__________________
AS3 | www.FLAPS.ru | Русские флэшеры самые умные флэшеры в мире. ©

Старый 08.09.2006, 16:06
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 4  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
Верно. И если после removeChild на клип не осталось других ссылок, то клип удаляется полностью (теоретически, как это проверить не знаю).
Но если у клипа были добавлены какие-либо события, то он не удалится, пока их не освободит.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 08.09.2006, 18:03
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 5  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
Ваще пипец...
Кнопка (клип типа Button) при изменении состояний Up-Over-Down (мышку над ней провели) генерит событие Event.REMOVED, которое могут ловят все ее родители
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 08.09.2006, 18:19
Nirth вне форума Посмотреть профиль Отправить личное сообщение для Nirth Посетить домашнюю страницу Nirth Найти все сообщения от Nirth
  № 6  
Ответить с цитированием
Nirth
4AM Games
 
Аватар для Nirth

блогер
Регистрация: Nov 2002
Адрес: Sofia
Сообщений: 6,264
Записей в блоге: 1
Отправить сообщение для Nirth с помощью ICQ Отправить сообщение для Nirth с помощью AIM Отправить сообщение для Nirth с помощью MSN Отправить сообщение для Nirth с помощью Yahoo Отправить сообщение для Nirth с помощью Skype™
аксиома ас1-2 :не используйте кнопки юзайте мувиклипы, в ас3 претерпела совсем немного изменений : не юзайте кнопки юзайте спрайты
__________________
Я перестал переписывать, начал редактировать, еще лет 15 и я стану писателем ^_^

Старый 09.09.2006, 01:16
FlexBuilder вне форума Посмотреть профиль Отправить личное сообщение для FlexBuilder Найти все сообщения от FlexBuilder
  № 7  
Ответить с цитированием
FlexBuilder

Регистрация: Aug 2006
Сообщений: 70
По поводу garbage collector-а... Как он коллектит гарбадж - только ему самому известно. Но то, что он его коллектит - это факт.
По моим наблюдениям убивание ссылок на объект, не приводит к мгновеному физическому уничтожению объекта из памяти - то же касается обработчиков с WeakReference, но через некоторое время объект все-таки удаляется. В частности после удаления последней ссылки обработчик onEnterFrame может еще сработать до 2000 раз, после чего останавливается. Из чего можно сделать вывод, что garbage collector чистит память либо с некоторым периодом, либо с некоторой задержкой.
По поводу setInerval - не рекомендуется использовать по соображениям стиля программирования. Эта процедура, скажем так, не вполне объектно-ориентированная, со всеми вытекающими последствиями.

Старый 11.09.2006, 15:06
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 8  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
Цитата:
Сообщение от FlexBuilder
...то же касается обработчиков с WeakReference, но через некоторое время объект все-таки удаляется. В частности после удаления последней ссылки обработчик onEnterFrame может еще сработать до 2000 раз, после чего останавливается...
Можно пример? Вот такой скрипт
Код:
package {
	import flash.display.Sprite;
	import flash.events.*;
	import flash.utils.*;

	dynamic public class Test extends Sprite {
		private var i:Number = 0;

		function Test():void {
			addEventListener(Event.ENTER_FRAME, doEnterFrame, false,0,true);
			addEventListener(MouseEvent.CLICK, doClick, false,0,true);
		}

		function doEnterFrame(e:Event):void {
			trace(getTimer());
		}

		function doClick(e:Event):void {
			parent.removeChild(this);
		}
	}
}
После клика и исчезновения проработал 2 часа и останавливаться не собирался.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 11.09.2006, 22:15
artcraft вне форума Посмотреть профиль Отправить личное сообщение для artcraft Посетить домашнюю страницу artcraft Найти все сообщения от artcraft
  № 9  
Ответить с цитированием
artcraft
 
Аватар для artcraft

блогер
Регистрация: Aug 2005
Адрес: www.artcraft.cz
Сообщений: 1,967
Записей в блоге: 6
Отправить сообщение для artcraft с помощью ICQ
A *very* important thing to understand about the Garbage Collector in FP9 is that it's operations are deferred. Your objects will not be removed immediately when all active references are deleted, instead they will be removed at some indeterminate time in the future (from a developer standpoint). The GC uses a set of heuristics that look at RAM allocation and the size of the memory stack (among other things) to determine when to run. As a developer, you must accept that fact that you will have no way of knowing when (or even if) your inactive objects will get deallocated. You must also be aware that inactive objects will continue to execute indefinitely (until the GC deallocates it), so code will keep running (ex. enterFrames), sounds will keep playing, loads will keep happening, events will keep firing, etc.

It's very important to remember that you have no control over when your objects will be deallocated, so you must make them as inert as possible when you are finished with them.


вот
__________________
Хороший отдых - половина работы.

Старый 11.09.2006, 22:50
artcraft вне форума Посмотреть профиль Отправить личное сообщение для artcraft Посетить домашнюю страницу artcraft Найти все сообщения от artcraft
  № 10  
Ответить с цитированием
artcraft
 
Аватар для artcraft

блогер
Регистрация: Aug 2005
Адрес: www.artcraft.cz
Сообщений: 1,967
Записей в блоге: 6
Отправить сообщение для artcraft с помощью ICQ
Unsupported Way to Force GC
There is a trick that will let you force the Flash player to carry out a full GC pass. This trick can be really handy for exploring Garbage Collection, and testing your applications during development, but it should never be deployed in production code because it can wreak havoc with processor load. It is also officially unsupported, so you cannot rely on it to work in updated versions of the player.

To force an immediate GC mark/sweep, all you have to do is call connect() on two LocalConnections with the same name. This will throw an error, so you'll have to wrap it in a try/catch block.
Код:
try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}
// the GC will perform a full mark/sweep on the second call.
Again, this should only be used as a development aid. It should never be used in production code!
__________________
Хороший отдых - половина работы.

Создать новую тему Ответ Часовой пояс GMT +4, время: 02:52.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 02:52.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.