Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как передать параметр в фунцию, вызванную addEventListener'ом? (http://www.flasher.ru/forum/showthread.php?t=138562)

TanaTiX 19.01.2012 20:54

DnV, во флеше замыкания - зло.

etc 19.01.2012 22:39

Цитата:

Сообщение от DnV (Сообщение 1057984)
Для передачи именно текущего объекта можно использовать замыкание:
Код AS3:

loader.addEventListener(Event.COMPLETE, function(f){return function(e:Event):void{completeEvent(e, f)}}(file));

Сценарий использования - параллельная загрузка файлов с их последующим сохранением под своими именами.
Вместо этого, конечно, можно наследовать URLLoader и хранить каждый файл в экземпляре класса загрузчика.

Наглядный пример того, как делать не надо.

DnV 20.01.2012 01:31

etc, значит можно заносить в FAQ, там кроме "зло" ничего вразумительного про замыкания нет :) А это, между прочим, самый простой способ. И так ли оно смертельно в данном случае? Если событие происходит крайне редко, мало того, для каждого экземпляра загрузчика единожды, чего ради городить свои классы?

TanaTiX 20.01.2012 01:52

DnV, каждый раз при вызове такого метода (вы кстати путаете класс и метод) создается новый экземпляр объекта, который не удаляется (где-то на форуме было). К тому же это крайне не удобно в отладке и разработке. Да и что мешает создать нормальный обработчик?

DnV 20.01.2012 02:20

TanaTiX, классы и методы я не путаю, нет :) За ссылку к обсуждению на форуме этой проблемы буду благодарен.

TanaTiX 20.01.2012 03:21

Тут обсуждалось.

DnV 20.01.2012 12:51

TanaTiX, спасибо. Поведение, о котором пишет BlooDHounD всё же предсказуемо. Да, сложнее дебажить. По поводу памяти, я не знаю как именно работает getSize, но даже если вложенная функция весит на пол килобайта больше, в ряде случаев это не важно. Сравнивать их тоже обычно не приходится. В общем, достаточно просто учитывать эти особенности и можно смело пользоваться. В ряде случаев (включая мой пример) проблем не будет.

expl 20.01.2012 13:30

Мне на вопрос "Дык иногда же очень удобно использовать анонимные функции" тимлид рассказал как он снизил потребление памяти в проекте с 800 до 200 MB повыпилив от туда анонимки.

Функция то сама может и не много весит - несколько килобайт, только вот она может захватить контекст, весящий десятки метров (например, если вы баловались внутри BitmapData-ми, а потом повесили ее как обработчик, да так она там и провисела пока флешплеер не закрыли)

iNils 20.01.2012 13:50

Цитата:

Сообщение от DnV (Сообщение 1058104)
общем, достаточно просто учитывать эти особенности и можно смело пользоваться. В ряде случаев (включая мой пример) проблем не будет.

Очередная медвежья услуга. Проблема не в том, что нужно учитывать особенности, а в том, что очередной новичек проигнорирует это предупреждение, так как их просто не понимает и начнет городить огород. И в результате мы получим еще одного быдло-кодера, потому что привыкнет писать абы как, а не сразу нормально.

В общем, достаточно просто учитывать, что анонимы создают проблемы и не использовать их. Вообще не использовать. Забыть и все.

wvxvw 21.01.2012 16:13

Давайте внесем немного ясности: замыкание - это не зло, уже хотябы потому, что оно неизбежно случается с любой функцией :) Замыканием называют лексическое окружение конкретного экземпляра функции. Так, например у функции f из примера ниже замыкание содержит связанные переменные y и z, и свободную переменную x, группа переменных {x, y, z} называется замыканием. В некоторых, очень часто встречающихся в AS3 ситуациях в заыкание неявно добавляются еще 2 переменные - this и super.
Код AS3:

var x:int;
function f(z:int):int
{
        var y:int = 42;
        return y + x + z;
}

Замыкание - это теоретическая концепция, она не обязана быть явно выражена в коде (в реализации того или другого языка), но, как только в языке программирования есть функции, имеет смысл говорить о замыканиях.
Теперь по-сути вопроса: использование анонимной функции в качестве слушателя. В AS3 - это плохая практика по причине плохой реализации анонимных функций и контекстных привязок для них. В чем это выражается: сначала о привязках, привязка в лексической среде подразумевает связывание значения с именем. Так, в примере выше значение 42 связано с именем y. Пока вы оперирует константами (числа - константы), то разницу вы не увидите, но, как только вы столкнетесь с необходимостью лексически связать сложную структуру с именем, у вас возникнут две принципиально разные возможности это сделать. Вы можете создавать структуру каждый раз как функция выполняется, а можете создать ее всего один раз. Последнее имеет смысл для функций, т.как типично, вы не захотите создавать одну и ту же функцию много раз. К сожалению, в AS3 нет возможности управлять типом связывания, и все связывания делаются динамически - это значит, что функция объявленная внутри другой функции всегда будет создана повторно, при повторном вызове внешней функции. Это, во-первых, естесственно, нееффективно (т.как вы создаете абсолютно никому не нужную копию, при том, что вполне могли бы использовать уже существующую), чревато, т.как даже если вам не нужно сравнивать функции, EventDispatcher это делает каждый раз, когда диспатчит событие и значительная часть его логики завязана на сравнении функций.
Из практических соображений, нет никаких преимуществ в использовании вложенных функций, но, как уже было сказано, неудобства при отладке, да и просто форматирование кода... вобщем, кругом одни недостатки и никаких достоинств. Вот, поэтому, вложенными функциями и не пользуются.

Azrael 06.02.2017 22:47

Подскажите и мне ответ на тот же вопрос. В классе А создаю класс B (PlayScreen) и передаю в его конструктор некоторый порядковый номер:

Код AS3:

PlayScr = new PlayScreen(1);

Далее в классе PlayScreen в его конструкторе происходит дальнейшая передача этого порядкового номера следующей функцие:

Код AS1/AS2:

public class PlayScreen extends Sprite 
{
public function PlayScreen(PlayerElement:int)
{
DrawField(PlayerElement);
}
}

И вот в функции DrawField на мувиклип вешается обработчик события которому тоже нужно передать этот порядковый номер - как передать?
Код AS3:

function DrawField(PlrElmntIndx:int)
{
cell = new MyClass;
cell.addEventListener(MouseEvent.CLICK, onCellClick);
}

Как бы мне в обработчике onCellClick получить доступ к PlayerElement?

Nooob 06.02.2017 23:53

Код AS3:

public class MyPlayerElementClass extends MyClass
{
    public var playerElement:int;
    public function MyPlayerElementClass(playerElement:int)
    {
        super();
        this.playerElement = playerElement;
    }
}
 
function drawField(playerElement:int)
{
    var cell:MyPlayerElementClass = new MyPlayerElementClass(playerElement);
    cell.addEventListener(MouseEvent.CLICK, onCellClick);
}
 
function onCellClick(event:MouseEvent)
{
    var cell:MyPlayerElementClass = event.currentTarget as MyPlayerElementClass;
    trace(cell.playerElement);
}

Код AS3:

        var dictionary:Dictionary = new Dictionary();
        function drawField(playerElement:int)
        {
                var cell:MyClass = new MyClass();
                dictionary[cell] = playerElement;
                cell.addEventListener(MouseEvent.CLICK, onCellClick);
        }
        function onCellClick(event:MouseEvent)
        {
                trace(dictionary[event.currentTarget]);
        }



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

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