Если вы удаляете все ссылки на родительский объект, нет необходимости удалять его дочерние объекты или прослушиватели дочерних объектов, при условии, что нет внешних ссылок на дочерние объекты.
Мусор с разметкой метокКоллектор работает путем обхода графа объекта, начиная с самого верхнего объекта (т. е. рабочей области).Отрежьте все пути к части графика, и весь этот подграф будет иметь право на сбор, независимо от каких-либо ссылок, которые подграф имеет между собой.
Сначала давайте рассмотрим только иерархию списка отображения без событий:
var clip:Sprite = new Sprite();
addChild(clip);
var clip2 = new Sprite();
clip.addChild(clip2);
// cleanup
removeChild(clip);
clip = null;
clip2 = null;
Внутренний дочерний клип2 будет собирать мусор, даже если мы не удалили его из родительского элемента с помощью clip.removeChild(clip2)
.Так как мы удалили все ссылки на родительский clip
и явную ссылку clip2
, нет доступа к нему, поэтому он будет собирать мусор.Поэтому нет необходимости removeChild
клипов-потомков.Просто убедитесь, что вы удалили все внешние ссылки на них (в данном случае clip2
).
Теперь давайте представим некоторые события:
var clip:Sprite = new Sprite();
addChild(clip);
clip.addEventListener(MouseEvent.CLICK, someListener);
var clip2:Sprite = new Sprite();
clip.addChild(clip2);
clip2.addEventListener(MouseEvent.CLICK, someOtherListener);
// cleanup -- the same!
removeChild(clip);
clip = null;
clip2 = null;
Вы можете подумать, что вам нужно удалитьслушатели событий, но на самом деле это не обязательно. addEventListener создает ссылку от диспетчера к слушателю .То есть добавление слушателей к дочерним объектам не помешает их сборке мусора.В этом случае addEventListener
делает ссылку с клипа на корень, а клип2 на корень.Когда происходит сборка мусора, маркер не может перейти от корня к клипу, даже если этот слушатель находится там.Ссылка идет в другом направлении , от клипа к корню!Таким образом, объекты по-прежнему будут собирать мусор.Следовательно, в этом случае нет необходимости удалять слушателей.Тем не менее, это не помешает сделать это, если вы не уверены.
Единственный способ, которым слушатели могут предотвратить сборку мусора, это если дочерний клип прослушивает родительский клип:
// from inside clip
root.addEventListener(MouseEvent.CLICK, someHandler);
Этот слушатель создает ссылку из корня в клип, поэтому вы должны либо удалить эту ссылку, либо использовать слабые ссылки.Поскольку вы используете слабые ссылки, вам не нужно об этом беспокоиться.
Это действительно много, чтобы отслеживать, и легко ошибиться, поэтому это хорошопотренируйтесь, чтобы удалить слушателей, когда вы закончите с ними .Вы всегда будете в безопасности, если уберете их.Это очень важно со странными нативными событиями, которые Flash отправляет вам, такими как Event.ENTER_FRAME и KeyboardEvent.KEY_DOWN, но не из-за проблем со сборкой мусора: даже если клип не имеет ссылок и имеет право на сбор, он будет продолжать получатьСобытия ENTER_FRAME, пока сборщик мусора не запустится в какой-то неопределенной точке в будущем.Поэтому вы ВСЕГДА должны удалять слушателей ENTER_FRAME.
Но в случае небольшого графа объектов с простыми MouseEvents, все будет в порядке, даже если вы не потрудитесь удалить слушателей.Они ничему не причиняют вреда и больше не будут отправляться после удаления клипа из списка отображения.Вы можете просто removeChild
родительский клип и покончить с этим.
Если вы хотите посмотреть, что происходит, может быть полезно использовать инструменты профилировщика в Flash Builder, FlashDevelop или FDT длявзгляните на использование памяти.Вы также можете использовать вызов System.gc();
, чтобы заставить GC работать в режиме отладки, если вы хотите проверить эти идеи.