PDA

Просмотр полной версии : Удаление событийного объекта


romanlysenko
22.12.2015, 02:56
Всем привет!
Кто может подсказать следующее:
всем знаком метод и событийный объект:
addEventListener(Event.ADDED_TO_STAGE, onStage);
допустим я его зарегистрировал в конструкторе основного класса Main:
public function Main():void {
addEventListener(Event.ADDED_TO_STAGE, onStage);
}
после того как вызывается метод onStage:
private function onStage(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, onStage);

addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
мы видим что событийный объект Event.ADDED_TO_STAGE передаваемый в качестве аргумента в параметр e метода onStage тут же принимает значение null (удаляется из памяти), а в теле самого метода/функции onStage удаляется слушатель данного события removeEventListener(Event.ADDED_TO_STAGE, onStage) и это понятно, но меня интересует собственно сам параметр e и присваиваемое ему значение null. Вот сама суть вопроса: я зарегистрировал в методе onStage слушатель события на соб. объект Event.ENTER_FRAME, вызываю метод onEnterFrame и в его параметре присваиваю событийному объекту значение null как с методом onStage:
private function onEnterFrame(e:Event = null):void {
...
}

Все работает, никаких ошибок...
Но правильно ли это, присваивать каждый раз параметру функции onEnterFrame значение null?

faraday
22.12.2015, 03:09
вы присваиваете объект события в переменную. так же можете ее и обнулить. сам объект при этом никуда не девается. а эта конструкция означает что по умолчанию переменная e равна null(если функция вызвана без аргумента)

romanlysenko
22.12.2015, 03:23
Ах да, точно, торможу немного...
Тогда изменим пример, точнее просто добавим в тело функции onEnterFrame следующий код:
private function onEnterFrame(e:Event = null):void {
e = null;
}

Ну теперь уже точно параметр e содержит соб. объект Event.ADDED_TO_STAGE и в теле самого метода обнуляет его, верно?
И опять вопрос, правильно ли это, стоит ли так писать и удаляет ли сборщик мусора каждый раз эту локальную переменную, да и вообще освобождается хоть чуть-чуть память?

caseyryan
22.12.2015, 06:43
Нет, не верно. Это всего навсего локальная переменная, и присвоение ей значения null ничего не дает.
Да и вообще, присвоение null значения означает всего-лишь зануление ссылки на объект в конкретном месте. Это ни в коем случае не удаляет ничего из памяти и не означает, что на него нет других ссылок и он доступен для сборщика мусора. В as3 вообще нет средств для удаления чего-либо из памяти вручную. Если на объект занулить все ссылки, то он становится доступным для сборщика мусора, но и это не означает, что он его сразу удалит. Удаления мусора - это довольно ресурсозатратная операция, поэтому он копит определенное количество, и только после превышения разрешенного объема, начинает процесс удаления.
Во время удаления мусора может легко провисать FPS или приложения может даже вообще на какое-то время остановиться, поэтому лучше не избавляться от ненужных в данный момент объектов, а по возможности использовать пулы. Но событий это не касается. Для них достаточно отписаться от слушателя.

Я бы посоветовал почитать как работают ссылки в C++, там работа с памятью описана гораздо подробнее, и что такое ссылки и адреса в памяти будет намного яснее

Ну и, конечно же, по as3 (http://help.adobe.com/ru_RU/as3/mobile/WS4bebcd66a74275c3-576ba64d124318d7189-7ffc.html)

zCHESNOKz
22.12.2015, 10:22
В as3 вообще нет средств для удаления чего-либо из памяти вручную.



А мне вот все таки интересно, почему так? Чем это обосновано, что плохого в самостоятельном управлении памятью?

i.o.
22.12.2015, 10:58
В том, что платформа со сбощиком мусора, который занимается тем, что освобождает память, когда объекты никем не используются. Вообще бессымысленно заморачиваться на "удалении" объекта события. Даже если слушателей миллиард, то объект события будет один (за исключение ручного редиспатчинга)

caseyryan
22.12.2015, 11:01
А мне вот все таки интересно, почему так? Чем это обосновано, что плохого в самостоятельном управлении памятью?
Вряд ли у тебя получится это правильно делать. Если бы адресация и удаление из памяти были такими простыми задачами, никто бы не придумывал разных сборщиков мусора

callme
22.12.2015, 11:04
romanlysenko

var a:TextField = new TextField();
var b:TextField = a;
var c:TextField = a;

Переменные "a" "b" "c" лежат в памяти, каждый по своему адресу. Текстфилд тоже лежит по своему адресу. По тем адресам, где лежат переменные, хранится только адрес текстфилда и больше ничего.

То есть переменные сами лежат по каким то адресам и хранят какие-то адреса. А по тому адресу где лежит текстфилд, вот там да - лежит настоящий текстфилд.

Если мы напишем a = null; то по тому адресу где хранится переменная "а" удалится адрес текстфилда, теперь там будет храниться число "0".

В переменных "b" и "c" все еще лежит адрес текстфилда.