ActionScript 3 - Полное удаление ребенка

У меня есть массив объектов, который, когда другой объект попадает в один из них, будет удален. Я удалил его со сцены с помощью removeChild () и удалил из массива с помощью splice (), но каким-то образом объект все еще вызывает некоторые из своих функций, что вызывает ошибки. Как полностью избавиться от объекта? К нему также не привязаны прослушиватели событий.

что вы имеете в виду, когда говорите «другой объект попадает в один из них»?

mmattax 16.09.2008 07:04

Я тестирую на столкновение с помощью hitTestObject, если это правда, то я хочу, чтобы объект из массива был полностью удален из памяти.

Brandon 16.09.2008 07:55
[UX] Категории и настройки внешнего вида Flash-сообщений
[UX] Категории и настройки внешнего вида Flash-сообщений
Flash-сообщение - это обычный веб-элемент, используемый для отправки короткого сообщения пользователю. Например, на странице входа в систему может...
3
2
19 929
7

Ответы 7

Похоже, у вас может быть проблема со сборкой мусора с флэш-плеером.

В Flash Player 10 был добавлен новый API, который должен решить эту проблему:

unloadAndStop ()

Грант Скиннер имеет больше информации об этом в своем блоге: http://www.gskinner.com/blog/archives/2008/07/unloadandstop_i.html

Вы можете получить бета-версию Flash Player 10 по адресу:

http://labs.adobe.com/technologies/flashplayer10/

Майк Чемберс

[email protected]

Является ли рассматриваемый объект MovieClip и воспроизводится ли на нем временная шкала? В таком случае вам нужно будет остановить его перед удалением. Также имейте в виду, что сохранение ссылки на объект любым способом (хотя чаще всего в прослушивателе событий) предотвратит сборку мусора. Сюда входят любые ссылки на функции или дочерние объекты.

Для вызова функции по определению должен быть либо слушатель, либо setTimeOut где-то, либо временная шкала должна воспроизводиться. Убедитесь, что вы удалили всех слушателей и все ссылки на объект. Что это за объект?

Окно вывода или отладчик должны показать вам стек вызовов функций, которые привели к нежелательному вызову. Если вы вставите сообщение об ошибке в свой вопрос, мы сможем дать вам более точный ответ.

Также не забудьте остановить и удалить все связанные таймеры при утилизации удаленных объектов: BIT-101: работающие таймеры не собираются сборщиком мусора. Всегда.

Убедитесь, что удаляемый экранный объект:

  • не имеет зарегистрированных на сцене слушателей, например вам нужно вызвать stage.removeEventListener(...) для любого соответствующего stage.addEventListener(...)
  • не имеет слушателя для события Event.ENTER_FRAME
  • не слушает события на таймерах
  • нигде не вызывается таймером, установленным с setInterval
  • и т. д. в основном все, что связано с таймерами, этапом, его родителем, загрузчиками и временной шкалой, может привести к тому, что объекты задержатся и не будут удалены

Поэтому, когда вы удалили объект с помощью removeChild и удалили его из массива, в котором вы его хранили, также вызовите его метод stop, чтобы убедиться, что он не воспроизводит свою временную шкалу. Также может быть хорошо иметь метод для этого объекта, называемый чем-то вроде halt, cleanup или finalize, который отменяет регистрацию любых слушателей, останавливает таймеры, тайм-ауты, интервалы и т.д., очищает ссылки (то есть устанавливает переменные в null) на его родительский , сцена или любой объект, который тоже никуда не денется.

Отличный совет. Большое спасибо. Мне особенно нравится последний абзац о добавлении отдельной функции для решения этой проблемы. Умная.

Richard 04.11.2011 20:56

Я бы посмотрел на слушателей Event.ENTER_FRAME и TimerEvent.TIMER, чтобы убедиться, что они обнулены, прежде чем удалять объект.

Чтобы полностью избавиться от объекта в AS3, вы должны установить для него значение null. При сборке мусора не возникнет проблем с его удалением, потому что на него нет ссылок. Также может быть полезно использовать «слабые ссылки» со слушателями событий. При создании прослушивателя событий обычно используется тип события и функция, которую нужно запустить.

addEventListener(SomeEvent.EVENT_HAPPEND, onEventHappend);

ниже я проиллюстрирую то же самое, но со слабой ссылкой.

addEventListener(SomeEvent.EVENT_HAPPEND, onEventHappend, false, 0, true);

Мы знаем, каковы первые два параметра, поэтому давайте начнем с третьего. Третий параметр определяет, запускает ли событие функцию onEventHappened во время фазы захвата (true) или фазы восходящей цепочки (false, что также является значением по умолчанию). Единственная причина, по которой я упоминаю этот параметр, заключается в том, что он требуется до установки параметра слабой ссылки. Четвертый параметр - это приоритет, он определяет, какие события имеют приоритет при прослушивании одного и того же объекта и одной и той же фазы потока событий. Пятый параметр устанавливает для слабой ссылки значение true или false, в этом случае мы будем использовать true, что полезно для сборки мусора.

Другие вопросы по теме