|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Автоматическое удаление всех потомков и прослушивателей
Всем привет,
Давайте представим такую ситуацию, что Вы создали страничку. На ней много картинок, кнопок с прослушивателями, пользовательский курсор да еще и прицепленный к stage ENTER_FRAME. Вы ее посмотрели и захотели закрыть. Сделав так: page = null, у нас в итоге все прослушиватели остануться висеть в памяти. Тогда что удалять каждый прослушиватель ручками? Нет это не наш путь, нам ведь так лениво! Вместо кропотливой писанины по удалению прослушивателей давайте лучше будем наследовать все классы где установлены прослушиватели от класса Basic. Тогда используя addEL можно устанавливать прослушиватели и заодно их регистрировать. А для очистки страницы используем метод free(page). Хотел добавить эту запись в блог, чтобы тема не потерялась, но видно не судьба... package { import flash.display.* import flash.events.* import flash.utils.* public class Basic extends Sprite { //Массив установленных прослушивателей public var myArrayListeners:Array = []; /** * Ставим прослушиватель и метку * @param conteiner * @param type * @param listener * @param useCapture * @param priority * @param useWeakReference * @param onStage */ public function addEL(conteiner:Object,type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void { //Добавляем слушатель только, если такого слушателя еще нет var instance:Object var aLengh:uint = myArrayListeners.length for (var i:uint = 0; i < aLengh; i++ ) { instance = myArrayListeners[i] //Находим элемент из массива if (instance.type == type && instance.listener == listener && instance.conteiner == conteiner) { //throw new Error("Такой прослушиватель уже есть"); return } } //Добавляем прослушиватель после проверки conteiner.addEventListener (type, listener, useCapture, priority, useWeakReference); //Добавляем в массив метку myArrayListeners.push( { type:type, listener:listener, conteiner:conteiner } ); } /** * Удаляем прослушиватель и убираем метку * @param conteiner * @param type * @param listener * @param useCapture * @param onStage */ public function removeEL(conteiner:Object,type:String, listener:Function, useCapture:Boolean = true):void { //Находим в массиве флаг слушатель которого удалили var instance:Object var aLengh:uint = myArrayListeners.length for (var i:uint = 0; i < aLengh; i++ ) { instance = myArrayListeners[i] //Находим и удаляем элемент из массива if (instance.type == type && instance.listener == listener && instance.conteiner == conteiner) { conteiner.removeEventListener (type, listener, useCapture); myArrayListeners.splice(i, 1) return } } } /** * Очистка контейнеров от данных * @param conteiner * @param clearAll */ public function free(conteiner:Object, clearAll:Boolean = false):void { if(conteiner!=null){ //Определяем класс полученного контейнера var myClass:Class = getDefinitionByName(getQualifiedClassName(conteiner)) as Class; //Обрабатываем объект var cLength:uint = 0 if (myClass == Array) { //Размер массива cLength = conteiner.length //Очищаем массив от объектов while (--cLength > -1) { //Ощищаем и объекты входящие в данный объект free(conteiner[cLength]) //Удаляем компоненты conteiner.splice(cLength, 1); } } cLength = 0 if (myClass == Object) { //Очищаем контейнер от объектов for (var item1:String in conteiner) { //Ощищаем и объекты входящие в данный объект free(conteiner[item1]) //Удаляем объект delete conteiner[item1] } } //Создаем локальную переменную var localArrayListeners:Array //Проверяем массив прослушивателей var checkListeners:Boolean = conteiner.hasOwnProperty("myArrayListeners") //Если есть, то работаем с ней if (checkListeners) { localArrayListeners = conteiner.myArrayListeners }else { localArrayListeners = myArrayListeners } //Проверяем есть ли потомки var checkСhildrens:Boolean = conteiner.hasOwnProperty("numChildren") //Обрабатываем спрайты if (checkСhildrens) { //Очищаем контейнер от прослушивателей var instance:Object //Создаем локальные переменные var localConteiner:Object //Проходим по всем сохраненным прослушивателям for (var j:uint = 0; j < localArrayListeners.length; j++ ) { //Передаем объект по ссылке instance = localArrayListeners[j] localConteiner = conteiner //Проверяем имена дочерних элементов и удаляем у них прослушиватели if (localConteiner.hasEventListener(instance.type) == true) { //Проверяем класс, чтобы не перебирать лишние элементы if (instance.conteiner == localConteiner) { //Удаляем прослушиватель localConteiner.removeEventListener(instance.type, instance.listener,false) localConteiner.removeEventListener(instance.type, instance.listener, true) //Если прослушиватель удален, то удаляем метку из массива прослушивателей if (localConteiner.hasEventListener(instance.type) == false) { localArrayListeners.splice(j, 1) //Так как размер массива изменился и данные сместились,то смещаем и счетчик j-- } } } } //Очищаем контейнер от объектов //Колличество дочерних элементов if (conteiner.numChildren != null) { cLength = conteiner.numChildren if (cLength != 0) { for (var i:uint = 0; i < cLength; i++) { //Ощищаем и объекты входящие в данный объект free(conteiner.getChildAt(0)) //Удаляем объект conteiner.removeChildAt(0) } } } //Удаляем сам контейнер if(clearAll == true){ conteiner.parent.removeChild(conteiner) conteiner = null } }else { //Очищаем картинку от данных var checkData:Boolean = conteiner.hasOwnProperty("bitmapData") //Если есть, то работаем с ней if (checkData) { conteiner.bitmapData.dispose() } } } } }} |
|
|||||
Banned
[+1 05.11.11]
[+1 09.08.11] Регистрация: Jan 2010
Адрес: РФ. Кемеровская область
Сообщений: 3,243
|
Для этого просто пишутся методы деструкторы, зануляющие все ненужное и удаляющие все слушатели.
Цитата:
|
|
|||||
Ужас.
1. Подписываться на ENTER_FRAME у stage в наследнике DisplayObject бессмысленно. ENTER_FRAME в него и так приходит. 2. Достаточно было переписать addEventListener / removeEventListener и не городить addEL / removeEL 3. Для useCapture создается отдельный слушатель, в вашем же случае удастся подписаться или с useCapture или без, но не вместе. 4. Класс объекта можно получить через: 5. Если в ваш Basic положить Bitmap, то он убьет и BitmapData, который может быть использован и в других битмапах. В дополнение, получите RTE, при очистке контейнера, если две битмапы с одной BitmapData будут в него помещены (или в разные контейнеры). 6. Словите RTE, если в Basic будет добавлен наследник DisplayObject, которому добавили свойство bitmapData или наследник Shape, которому добавили свойство numChildren. Цитата:
__________________
משיח לא בא משיח גם לא מטלפן |
|
|||||
Регистрация: Sep 2010
Адрес: Ростов-на-Дону
Сообщений: 369
|
Меня вот всегда интересовал вопрос: почему массив _listeners в EventDispatcher-е приватный, и разработчики не сделали к нему доступ, хотя бы через геттер. Не понимаю, чем это могло быть плохо?
|
|
|||||
|
|
|||||
Goodguy
Чтобы удалить прослушиватели, надо отловить момент удаления объектов прослушивателей. А так все под рукой и можно даже не писать деструкторы. Alatar 2. Да я не хочу переписывать их, так как они по-моему будут быстрее работать, если надо просто ручками удалять. 3. Не понимаю этот useCapture, всегда использую false и поэтому так все реализовал 4.Спс 5. Согласен использование Basic, налагает ряд ограничений, так как не все моменты охвачены. -Не знал, что один BitmapData можно сразу нескольким картинкам назначить. Обычно каждой делаю свою. Можно убрать этот dispose, после removeChild сборщик все равно уберет. -Класс могут наследовать только обьекты с numChildren. Bitmap хоть и имеет addEventListener, но у него не будут удаляться прослушиватели. Хотя это вроде можно реализовать. Но по мне так можно просто не вешать на такие объекты события. Mayakwd СПС большое! - Последний раз редактировалось Genm; 28.08.2011 в 22:59. |
|
|||||
Banned
[+1 05.11.11]
[+1 09.08.11] Регистрация: Jan 2010
Адрес: РФ. Кемеровская область
Сообщений: 3,243
|
Цитата:
|
|
|||||
goodguy
их - это объекты прослушивателей. Спс изменил... mayakwd Цитата:
|
|
|||||
Ну магии не место в программировании, поэтому, да, деструкторы необходимо писать :-)
|
|
|||||
Цитата:
__________________
...вселенская грусть |
Часовой пояс GMT +4, время: 07:27. |
|
« Предыдущая тема | Следующая тема » |
|
|