![]() |
После removeEventListener обработчик продолжает вызываться
Собственно заголовком все сказано, исходник ниже. Из вне создается несколько таких объектов. Я не могу догнать вобще как такое случилось, что после removeEventListener у меня продолжается вызываться обработчик.
обратите внимание на блок с trace("before", death.id) по trace("after", death.id); Код AS3:
before 10 before 13 before 99 before 2 before 51 before 127 before 126 before 128 after 10 after 13 after 99 after 2 after 51 after 127 after 126 after 128 after 128 after 126 after 128 after 127 after 126 after 128 after 51 after 127 after 126 after 128 after 2 after 51 after 127 after 126 after 128 after 99 after 2 after 51 after 127 after 126 after 128 after 13 after 99 after 2 after 51 after 127 after 126 after 128 Дабы хоть как-то решить вопрос пришлось сделать проверку на то, произошла ли уже загрузка в объекте или нет. Где я накосячил никак не могу понять :wacko: |
Видимо проблема в том что сам объект типа DeathImage несколько раз добавляется на сцену, или добавляется несколько объектов типа DeathImage подряд, и при каждом
Код AS3:
Короче по ходу не в этом классе проблема, а в том что добавляет этот самый DeathImages на сцену. |
Да, таких объектов добавляется подряд несколько, и каждый объект подписывается на данное событие и при получении события отписывается.
В итоге что получается, после того как первый объект от события отписался, второй следом подписался, предыдущий тоже оказывается подписанным? Я что-то запутался, видимо пора спать. |
Для каждого объекта в отдельности, при его добавлении на сцену будет срабатывать его же __addedToStage.
|
Ну, да, а при чем здесь __addedToStage?
|
Сделайте вот так при добавлении слушателя:
Код AS3:
Код AS3:
|
Добавление нескольких прослушивателей с одиниковым типом, обработчиком и целевой фазой не приводят к дополнительной регистрации прослушивателя, поэтому это не имеет смысла вовсе.
|
Либо в __imagesLoadComplete ссылка на controls.images это уже ссылка на другой объект и вы не того отписываете, либо вы его опять где-то подписываете на это событие.
В любом случае из этого куска кода не понять. |
Цитата:
Вобщем пришлось решать проблему тем, чтобы каждый экземпляр класса юзал отдельный controls.images, а не один и тот же. Ибо получается, что подпись на событие экземпляра controls.images подписывает также все другие экземпляры DeathImage, которые уже отписались от него. Честно говоря для меня это поведение неожиданность. Я считал что подпись осуществляется в пределах экземпляра класса, к которому принадлежит обработчик. Неужели это не так? |
Цитата:
|
Цитата:
А вот сам факт, что экземпляру EventDispatcher пофиг на то, в каком экземпляре его подписывают и посылает событие даже в те экземпляры, которые уже отписались от его события весьма странен. |
Цитата:
|
Цитата:
|
Я знаю только что если Вы от события отписались, то получать Вы его не будете.
|
А если я от него отписался, но подписался в другом экземпляре класса, первый не должен продолжать получать событие, так?
|
Да, все верно. Попробуйте провести эксперимент - создайте 2 Shape'а и подпишите их на Event.ENTER_FRAME. И отпишите. И потом по очереди подписывайте/отписывайте. Поймать какой именно Shape получил событие можно через свойство события target.
Уверен, что в итоге Вы убедитесь, что после отписки событие перестает обрабатываться. |
Я в этом уверен изначально.
Но только есть разница между экспериментом и исходником выше, в случае с шейпами, я буду подписыватсья на два разных объекта, а в моем случае я подписываюсь к одному и тому же объекту разными объектами. По идее это не должно иметь значения, просто к слову о разнице. Но у меня как-то так получилось. Вобщем никак не могу найти где я накосячил, но тем не менее из примера видно, что после отписи экземпляр продолжает обрабатывать событие, а после отписи конкретно данный экземпляр далее нигде не подписывается на это событие. |
Есть у меня теория по поводу происходящего. Опирается она на то, что controls.images у вас один на всех, и что при локальном тестировании загрузка происходит практически моментально, и поэтому объекты ловят события по несколько раз, прежде чем успевают отписаться.
Ошибка в том, что все экземпляры слушают Event.COMPLETE, но никто не знает, как отличить событие, вызванное загрузкой своих данных, от остальных точно таких же событий. Поэтому на завершение загрузки для одного экземпляра реагируют сразу все. В итоге происходит следующее: 1. Вы в цикле добавляете на сцену n экземпляров DeathImage. Каждый экземпляр подписывается на Event.COMPLETE у controls.images и запускает загрузку. 2. Завершается загрузка, вызванная 1м экземпляром; controls.images посылает Event.COMPLETE, который ловят ВСЕ экземпляры DeathImage. В очередь исполнения попадают __imagesLoadComplete всех экземпляров. 3. Начинает исполняться __imagesLoadComplete 1го экземпляра. Пока он исполняется, завершаются загрузки, вызванные остальными экземплярами. Каждая завершенная загрузка пуляет Event.COMPLETE, который кладет в очередь вызовов __imagesLoadComplete ВСЕХ ЭКЗЕМПЛЯРОВ КРОМЕ 1го (т.к. первый уже успел отписаться; это подтверждается тем, что "after 10" в трейсах выводится первым и встречается всего 1 раз). Итого на момент завершения исполнения __imagesLoadComplete 1го экземпляра в очереди вызовов находится n вызовов __imagesLoadComplete для всех экземпляров кроме 1го (по 1 уже было, по n-1 добавилось только что) и n-1 для 1го (1й вызов только что отработал, n-1 добавились) 4. Исполняется по 1 вызову __imagesLoadComplete для каждого экземпляра DeathImage. После этого все экземпляры отписаны от Event.COMPLETE, но в очереди УЖЕ ЛЕЖАТ оставшиеся n-1 вызовов __imagesLoadComplete для каждого экземпляра. 5. Для каждого экземпляра по очереди исполняются оставшиеся вызовы. В реальных условиях, когда загрузка происходит не моментально, и вызовы __imagesLoadComplete, вызванные первым Event.COMPLETE, успеют отработать ДО следующего Event.COMPLETE, все экземпляры успеют от него отписаться, и остальные n-1 событий никто не поймает. |
Gaen, да, все именно так и происходит, браво, я что-то подобное подозревал, но сварить все в кучу в голове не получалось, теперь есть четкое объяснение происходящего.
На самом деле картинки я загружаю с удаленного сервера, поэтому в боевых условиях ситуация будет такая же. Проблему решил отдельным экземпляром image для каждого подписывающегося объекта, а соответственно для каждого теперь своя очередь, но статический Dictionary загруженных изображений. Правда у этого подхода есть парочка небольших минусов, но они терпимы по сравнению с тем, что было. Такую дырень пришлось бы в любом случае закрывать, даже, если картинки грузились бы долго, т.к. в том случае, когда они уже в кеше браузера, им нужно совсем не много времени чтобы перекочевать в Dictionary. В любом случае, Gaen, большое спасибо, вы помогли мне объяснить эту ситуацию и я теперь не буду мучаться в догадках. |
| Часовой пояс GMT +4, время: 03:50. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.