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

Вернуться   Форум Flasher.ru > Блоги > Идиотизмы

Даже в определениях идиотизма встречается идиотизм.
Цитата:
Идиотизм — устаревшее название идиомы
Идиома в программировании — понятие близкое к понятию шаблона проектирования. Идиомы представляют собой шаблоны проектирования, учитывающие специфику конкретного языка программирования и потому не универсальные. Это хорошие решения проектирования для конкретного языка или программной платформы.
Рейтинг: 5.00. Голосов: 2.

Идиотизмы: множественный addedToStage.

Запись от BlooDHounD размещена 07.06.2010 в 20:58

для понимания материала необходимы следующие знания:
flash.display.DisplayObject


множественный addedToStage... Вы думаете, что addedToStage срабатывает единожды? как бы не так!
давайте составим цепочку, в которой где в хэдлере на addedToStage будем создавать спрайт и ложить в только что добавленный спрайт (target).
Код AS3:
package {
 
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class test extends Sprite {
 
        public function test() {
            var s1:Sprite = new Sprite();
            s1.addEventListener( Event.ADDED_TO_STAGE, this.handler_addedToStage );
            super.addChild( s1 );
        }
 
        private function handler_addedToStage(event:Event):void {
            var s2:Sprite = new Sprite();
            s2.addEventListener( Event.ADDED_TO_STAGE, trace );
            ( event.target as Sprite ).addChild( s2 );
        }
 
    }
 
}
после запуска, Вы с удивлением должны бы ли обнаружить в output две записи вместо одной.
что же произошло?

нам известно, что событие addedToStage срабатывает внутри вызова addChild. после отработки этого события, метод должен уведомить всех детей о том, что они тоже добавлены на сцену.
как это выглядит?
Код:
addChild
+dispatchEvent
++handler
+++addChild
++++dispatchEvent — первый наш трэйс
+dispatchChildsEvent — второй наш трэйс
соответственно мы можем увеличивать цепочку цепочку вложенности, и с каждой новой вложенностью наш ребёнок будет получать лишние событие.

обнаружил данную особенность ещё в незапамятные времени Дениска ( etcs.ru ). а я написал хак исправляющий данную штуку. все визуальные объекты у нас унаследованный от класса прослойки, в котором мы отлавливаем все лишнии addedToStage и останавливаем при помощи stopImmediatePropagation.

скорее всего это баг, но чёрт его знает. нам такое поведение не понравилось. исправляется этот баг добавлением одно if. либо выборки детей до первого диспатча. но править его не мне =)

хак:
Код AS3:
package blooddy.patch.display {
 
    import flash.display.Sprite;
    import flash.events.Event;
 
    /**
     * @author              BlooDHounD
     * @playerversion       Flash 9
     * @langversion         3.0
     */
    public class Sprite extends flash.display.Sprite {
 
        //--------------------------------------------------------------------------
        //
        //  Constructor
        //
        //--------------------------------------------------------------------------
 
        /**
         * Constructor
         */
        public function Sprite() {
            super();
            super.addEventListener( Event.ADDED_TO_STAGE,        this.handler_addedToStage,        false, int.MAX_VALUE, true );
            super.addEventListener( Event.REMOVED_FROM_STAGE,    this.handler_removedFromStage,    false, int.MAX_VALUE, true );
       }
 
        //--------------------------------------------------------------------------
        //
        //  Variables
        //
        //--------------------------------------------------------------------------
 
        /**
         * @private
         */
        private var _addedToStage:Boolean = false;
 
        //--------------------------------------------------------------------------
        //
        //  Event handlers
        //
        //--------------------------------------------------------------------------
 
        /**
         * @private
         */
        private function handler_addedToStage(event:Event):void {
            if ( this._addedToStage ) {
                event.stopImmediatePropagation();
            } else {
                this._addedToStage = true;
            }
        }
 
        /**
         * @private
         */
        private function handler_removedFromStage(event:Event):void {
            this._addedToStage = false;
        }
 
    }
 
}
Всего комментариев 7

Комментарии

Старый 31.01.2013 11:33 garymar вне форума
garymar
А кто слушатели удалять будет?
Старый 31.01.2013 12:07 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
А кто документацию читать будет?
Старый 31.01.2013 13:46 garymar вне форума
garymar
И что там в той документации? Тыкни носом меня.
Старый 31.01.2013 15:42 i.o. вне форума
i.o.
 
Аватар для i.o.
Четвертый параметр выставлен в true
Старый 01.02.2013 01:12 Котяра вне форума
Котяра
 
Аватар для Котяра
А зачем удалять слушатели на самого себя вообще?
Старый 01.02.2013 19:02 AlexLucas вне форума
AlexLucas
 
Аватар для AlexLucas
Спасибо за некропост
Буквально только что столкнулся с тем что addedToStage повторно вызывается, соответственно всё инициализируется дважды. Прочитал, и понял что это "нормально".
Старый 02.02.2013 16:56 garymar вне форума
garymar
Мне кажется это багом нельзя называть..
 

 


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


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