2010-06-13 2 views
2

Итак, я играл с Flash, просматривая документацию и все такое, и заметил, что событие ENTER_FRAME, похоже, не оправдывает мое ожидание детерминированной вселенной.
Рассмотрим следующий пример:Как происходит событие Actionscript 3 ENTER_FRAME - сумасшедшие орехи?

(new MovieClip()).addEventListener(Event.ENTER_FRAME, 
    function(ev) {trace("Test");}); 

Заметим, что это анонимный MovieClip не добавляется в иерархии отображения, и любая ссылка на него сразу теряется.

На самом деле он напечатает «Тест» после кадра, пока не будет собран мусор. Как это безумие? Поведение этого на самом деле определяется тем, что сборщик мусора чувствует, что он приближается во всем своем непредсказуемом безумии! Есть ли лучший способ создать прерывистые сбои? Серьезно.

Мои две теории состоят в том, что либо класс DisplayObject хранит слабые ссылки на все его экземпляры с целью отправки событий ENTER_FRAME, либо, и многое другое, Flash Player действительно просматривает кучу каждого кадра, ищущего прослушивание прослушивателей ENTER_FRAME ,

Может ли какой-нибудь затвердевший разработчик Actionscript подсказывать мне, как это работает? (И, может быть, почему именно? F ** k они думали, что это была хорошая идея?)

ответ

4

Короткий ответ: вы получаете то, о чем просите.

Тот факт, что ваш MovieClip является «анонимным», как вы его называете, не меняет работу мусора.

Обе ваши теории ошибочны. Это проще. Вы попросили свой экземпляр MovieClip уведомить вас всякий раз, когда вводится кадр. Цитата из docs:

Отправляется, когда точка воспроизведения переходит в новый кадр. Если головка воспроизведения не перемещается или имеется только один кадр , это событие отправляется непрерывно в сочетании с частотой кадров . Это событие отправляется одновременно ко всем отображаемым объектам прислушивается к этому событию.

И это то, что происходит.

Объекты, такие как MovieClips, выделены в виде кучи. Если вы храните ссылку на нее в локальной переменной, эта ссылка находится в стеке и выйдет из области действия при возврате из вашей функции. У вас не будет способа ссылаться на объект, , но объект все еще будет жив, в куче. Итак, сохраняете ли вы ссылку на экземпляр mc или нет, что не меняет этот основной факт работы кучи и мусора.

Теперь, так как они не являются сильными ссылками на этот объект, этот объект является elligible для коллекции. Это не означает, что он будет собран , когда функция вернет.

Поскольку объект все еще жив, он продолжит отправку события, потому что вы попросили его. Как только он будет собран, естественно, ваш код в обработчике больше не будет выполнен.

Редактировать

Я сказал, что оба ваших теорий являются неправильными. Я думаю, что это случай с точки зрения ActionScript. Однако на уровне игрока кажется очевидным, что игрок должен отслеживать объекты, на которых он должен запускать определенные события, поэтому да, он должен хранить внутреннюю ссылку на указанные объекты. Это не отличается от того, как он работает для других объектов, которые глобально обрабатываются игроком, хотя, например, например, загрузчики. Есть одно исключение из этого, о котором я знаю: запуск таймеров. Пока работает таймер, он не будет собран, даже если у вас нет ссылки на ActionScript.

+0

Удаленный ответ, не хочу вызывать путаницу. И ты прав. Это имеет смысл. Я всегда считал, что это так из-за легенд экспертов3 о слушателях и их ссылках. – mrkishi

+0

@MrKishi. Ну, я видел, как легенды ошибаются, даже в SO (я не имею в виду lengends саркастично, это ребята, которые делали потрясающие вещи). Во всяком случае, одной из наиболее распространенных ссылок на память и GC, вероятно, являются блоги Grant Skinner. Но если вы их прочтете, он не скажет, что добавление слушателей вызовет утечку. Он решительно выступает за отказ от слабых ссылок и хотя я могу не согласиться, его баллы действительны. Проблема в том, что многие люди просто получают эту часть и продвигаются дальше. Таким образом, у них есть упрощенное (и неправильное) понятие о том, что не удалять слушателя или не использовать слабый ref всегда будет вызывать утечки. –

+0

@ Juan: Я не знаю, почему суета о weakrefs, а также. Во всяком случае, я никогда не использую (анонимные?) Функции. Не изменилось бы. – mrkishi