Почему событие Actionscript 3 ENTER_FRAME является сумасшедшим? - PullRequest
2 голосов
/ 13 июня 2010

Итак, я возился с Flash, просматривал документацию и все такое и заметил, что событие ENTER_FRAME, похоже, не соответствует моим ожиданиям детерминированной вселенной.
Возьмите следующий пример:

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

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

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

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

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

1 Ответ

4 голосов
/ 13 июня 2010

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

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

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...